1
|
|
|
# |
2
|
|
|
# Copyright 2001 - 2016 Ludek Smid [http://www.ospace.net/] |
3
|
|
|
# |
4
|
|
|
# This file is part of Outer Space. |
5
|
|
|
# |
6
|
|
|
# Outer Space is free software; you can redistribute it and/or modify |
7
|
|
|
# it under the terms of the GNU General Public License as published by |
8
|
|
|
# the Free Software Foundation; either version 2 of the License, or |
9
|
|
|
# (at your option) any later version. |
10
|
|
|
# |
11
|
|
|
# Outer Space is distributed in the hope that it will be useful, |
12
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
13
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14
|
|
|
# GNU General Public License for more details. |
15
|
|
|
# |
16
|
|
|
# You should have received a copy of the GNU General Public License |
17
|
|
|
# along with Outer Space; if not, write to the Free Software |
18
|
|
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
19
|
|
|
# |
20
|
|
|
|
21
|
|
|
from Const import * |
22
|
|
|
from ige import GameException, SecurityException |
23
|
|
|
from ige.IDataHolder import IDataHolder |
24
|
|
|
import types |
25
|
|
|
import log |
26
|
|
|
|
27
|
|
|
def public(access): |
28
|
|
|
""" Decorator to mark methods public with appropriate access level. """ |
29
|
|
|
def public_decorator(func): |
30
|
|
|
func.public = True |
31
|
|
|
func.accLevel = access |
32
|
|
|
return func |
33
|
|
|
return public_decorator |
34
|
|
|
|
35
|
|
|
class IObject: |
36
|
|
|
|
37
|
|
|
typeID = T_OBJECT |
|
|
|
|
38
|
|
|
forums = [] |
39
|
|
|
|
40
|
|
|
def __init__(self, gameMngr): |
41
|
|
|
self.gameMngr = gameMngr |
42
|
|
|
self._cmd = gameMngr.cmdPool |
43
|
|
|
|
44
|
|
|
def cmd(self, obj): |
45
|
|
|
return self._cmd[obj.type] |
46
|
|
|
|
47
|
|
|
def new(self, type): |
48
|
|
|
obj = IDataHolder() |
49
|
|
|
self._cmd[type].init(obj) |
50
|
|
|
return obj |
51
|
|
|
|
52
|
|
|
def init(self, obj): |
53
|
|
|
# call superclass |
54
|
|
|
pass |
55
|
|
|
# define new attributes |
56
|
|
|
obj.oid = OID_NONE |
|
|
|
|
57
|
|
|
obj.type = self.typeID |
58
|
|
|
obj.owner = OID_NONE |
59
|
|
|
obj.compOf = OID_NONE |
60
|
|
|
obj.name = u'Unnamed' |
61
|
|
|
# not needed |
62
|
|
|
# obj.accRights = {} |
63
|
|
|
|
64
|
|
|
def getReferences(self, tran, obj): |
65
|
|
|
return None |
66
|
|
|
|
67
|
|
|
def upgrade(self, tran, obj): |
68
|
|
|
# call update method |
69
|
|
|
try: |
70
|
|
|
self.cmd(obj).update(tran, obj) |
71
|
|
|
except: |
72
|
|
|
log.warning("Cannot execute update method on", obj.oid) |
73
|
|
|
refObj = self.new(obj.type) |
74
|
|
|
new = refObj.__dict__.keys() |
75
|
|
|
old = obj.__dict__.keys() |
76
|
|
|
changed = 0 |
77
|
|
|
# change attributes |
78
|
|
|
# remove old |
79
|
|
|
for attr in old: |
80
|
|
|
if attr in new: |
81
|
|
|
#if type(getattr(obj, attr)) != type(getattr(refObj, attr)): |
82
|
|
|
#@log.debug('IObject', 'Upgrade - chng', obj.oid, obj.type, attr, type(getattr(obj, attr)), 'to', type(getattr(refObj, attr))) |
83
|
|
|
# TODO - enable |
84
|
|
|
#setattr(obj, attr, getattr(refObj, attr)) |
85
|
|
|
#changed = 1 |
86
|
|
|
new.remove(attr) |
87
|
|
|
else: |
88
|
|
|
log.debug('IObject', 'Upgrade - del', obj.oid, obj.type, attr) |
89
|
|
|
delattr(obj, attr) |
90
|
|
|
changed = 1 |
91
|
|
|
# set new |
92
|
|
|
for attr in new: |
93
|
|
|
log.debug('IObject', 'Upgrade - new', obj.oid, obj.type, attr) |
94
|
|
|
setattr(obj, attr, getattr(refObj, attr)) |
95
|
|
|
changed = 1 |
96
|
|
|
|
97
|
|
|
def update(self, tran, obj): |
98
|
|
|
pass |
99
|
|
|
|
100
|
|
|
update.public = 0 |
101
|
|
|
|
102
|
|
|
def loadDOMAttrs(self, obj, elem): |
103
|
|
|
for index in xrange(0, elem.attributes.length): |
|
|
|
|
104
|
|
|
attr = elem.attributes.item(index) |
105
|
|
|
if hasattr(obj, attr.nodeName): |
106
|
|
|
attrType = type(getattr(obj, attr.nodeName)) |
107
|
|
|
if attrType == types.IntType: |
108
|
|
|
value = int(attr.nodeValue) |
109
|
|
|
elif attrType == types.FloatType: |
110
|
|
|
value = float(attr.nodeValue) |
111
|
|
|
elif attrType == types.UnicodeType: |
112
|
|
|
value = attr.nodeValue |
113
|
|
|
elif attrType == types.StringType: |
114
|
|
|
value = attr.nodeValue |
115
|
|
|
else: |
116
|
|
|
raise 'Unsupported attribute type %s' % attrType |
117
|
|
|
setattr(obj, attr.nodeName, value) |
118
|
|
|
else: |
119
|
|
|
raise GameException('Unsupported attribute %s' % attr.nodeName) |
120
|
|
|
|
121
|
|
|
def getInfo(self, tran, obj): |
122
|
|
|
return obj |
123
|
|
|
|
124
|
|
|
getInfo.public = 1 |
125
|
|
|
getInfo.accLevel = AL_INFO |
|
|
|
|
126
|
|
|
|
127
|
|
|
def get(self, tran, obj): |
128
|
|
|
return self.cmd(obj).getInfo(tran, obj) |
129
|
|
|
|
130
|
|
|
get.public = 1 |
131
|
|
|
get.accLevel = AL_INFO |
132
|
|
|
|
133
|
|
|
def getPublicInfo(self, tran, obj): |
134
|
|
|
result = IDataHolder() |
135
|
|
|
result.oid = obj.oid |
136
|
|
|
return result |
137
|
|
|
|
138
|
|
|
getPublicInfo.public = 1 |
139
|
|
|
getPublicInfo.accLevel = AL_NONE |
|
|
|
|
140
|
|
|
|
141
|
|
|
def set(self, tran, obj, attr, value): |
142
|
|
|
if hasattr(obj, attr): |
143
|
|
|
setattr(obj, attr, value) |
144
|
|
|
return 1 |
145
|
|
|
raise GameException('No such attribute.') |
146
|
|
|
|
147
|
|
|
set.public = 1 |
148
|
|
|
set.accLevel = AL_ADMIN |
|
|
|
|
149
|
|
|
|
150
|
|
|
|
151
|
|
|
## messaging api |
152
|
|
|
def sendMsg(self, tran, obj, message): |
153
|
|
|
if tran.session.cid != OID_ADMIN: |
|
|
|
|
154
|
|
|
message["sender"] = tran.session.nick |
155
|
|
|
message["senderID"] = tran.session.cid |
156
|
|
|
# check attributes |
157
|
|
|
if "forum" not in message: |
158
|
|
|
raise GameException("Forum not specified.") |
159
|
|
|
if message["forum"] not in self.forums: |
160
|
|
|
raise GameException("No such forum.") |
161
|
|
|
if "topic" not in message: |
162
|
|
|
raise GameException("Topic not specified.") |
163
|
|
|
if "data" not in message and "text" not in message: |
164
|
|
|
raise GameException("Text or structured data not specified.") |
165
|
|
|
# check permissions |
166
|
|
|
if tran.session.cid != OID_ADMIN and \ |
167
|
|
|
not self.canSendMsg(tran, obj, message["senderID"], message["forum"]): |
168
|
|
|
raise SecurityException("You cannot send message to this entity.") |
169
|
|
|
# |
170
|
|
|
message["recipient"] = obj.name |
171
|
|
|
message["recipientID"] = obj.oid |
172
|
|
|
# send message |
173
|
|
|
return tran.gameMngr.msgMngr.send(tran.gameMngr.gameID, obj.oid, message) |
174
|
|
|
|
175
|
|
|
sendMsg.public = 1 |
176
|
|
|
sendMsg.accLevel = AL_NONE |
177
|
|
|
|
178
|
|
|
def sendAdminMsg(self, tran, obj, message): |
179
|
|
|
# check attributes |
180
|
|
|
if "forum" not in message: |
181
|
|
|
raise GameException("Forum not specified.") |
182
|
|
|
if message["forum"] not in self.forums: |
183
|
|
|
raise GameException("No such forum.") |
184
|
|
|
if "topic" not in message: |
185
|
|
|
raise GameException("Topic not specified.") |
186
|
|
|
if "data" not in message and "text" not in message: |
187
|
|
|
raise GameException("Text or structured data not specified.") |
188
|
|
|
# |
189
|
|
|
message["recipient"] = obj.name |
190
|
|
|
message["recipientID"] = obj.oid |
191
|
|
|
# send message |
192
|
|
|
return tran.gameMngr.msgMngr.send(tran.gameMngr.gameID, obj.oid, message) |
193
|
|
|
|
194
|
|
|
sendAdminMsg.public = 1 |
195
|
|
|
sendAdminMsg.accLevel = AL_ADMIN |
196
|
|
|
|
197
|
|
|
def getMsgs(self, tran, obj, lastID = -1): |
198
|
|
|
if not self.canGetMsgs(tran, obj, tran.session.cid): |
199
|
|
|
raise SecurityException("You cannot read messages of this entity.") |
200
|
|
|
# get messages |
201
|
|
|
return tran.gameMngr.msgMngr.get(tran.gameMngr.gameID, obj.oid, lastID) |
202
|
|
|
|
203
|
|
|
getMsgs.public = 1 |
204
|
|
|
getMsgs.accLevel = AL_NONE |
205
|
|
|
|
206
|
|
|
def deleteMsgs(self, tran, obj, ids): |
207
|
|
|
if not self.canManageMsgs(tran, obj, tran.session.cid): |
208
|
|
|
raise SecurityException("You cannot manage messages of this entity.") |
209
|
|
|
# get messages |
210
|
|
|
return tran.gameMngr.msgMngr.delete(tran.gameMngr.gameID, obj.oid, ids) |
211
|
|
|
|
212
|
|
|
deleteMsgs.public = 1 |
213
|
|
|
deleteMsgs.accLevel = AL_NONE |
214
|
|
|
|
215
|
|
|
def deleteOldMsgs(self, tran, obj): |
216
|
|
|
for forum in self.forums: |
217
|
|
|
tran.gameMngr.msgMngr.deleteOld(tran.gameMngr.gameID, obj.oid, forum, maxAge = self.forums[forum]) |
218
|
|
|
|
219
|
|
|
deleteOldMsgs.public = 1 |
220
|
|
|
deleteOldMsgs.accLevel = AL_ADMIN |
221
|
|
|
|
222
|
|
|
def canSendMsg(self, tran, obj, oid, forum): |
223
|
|
|
return 0 |
224
|
|
|
|
225
|
|
|
canSendMsg.public = 0 |
226
|
|
|
|
227
|
|
|
def canGetMsgs(self, tran, obj, oid): |
228
|
|
|
return oid == obj.oid |
229
|
|
|
|
230
|
|
|
canGetMsgs.public = 0 |
231
|
|
|
|
232
|
|
|
def canManageMsgs(self, tran, obj, oid): |
233
|
|
|
return oid == obj.oid or oid == OID_ADMIN |
|
|
|
|
234
|
|
|
|
235
|
|
|
canManageMsgs.public = 0 |
236
|
|
|
|
237
|
|
|
def getMailboxName(self, tran, obj): |
238
|
|
|
return (tran.gameMngr.gameID, obj.oid) |
239
|
|
|
|
240
|
|
|
getMailboxName.public = 0 |
241
|
|
|
|