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 | import types |
||
21 | |||
22 | import Const |
||
23 | import log |
||
24 | |||
25 | from ige import GameException, SecurityException |
||
26 | from ige.IDataHolder import IDataHolder |
||
27 | |||
28 | def public(access): |
||
29 | """ Decorator to mark methods public with appropriate access level. """ |
||
30 | def public_decorator(func): |
||
31 | func.public = True |
||
32 | func.accLevel = access |
||
33 | return func |
||
34 | return public_decorator |
||
35 | |||
36 | class IObject: |
||
37 | |||
38 | typeID = Const.T_OBJECT |
||
39 | forums = [] |
||
40 | |||
41 | def __init__(self, gameMngr): |
||
42 | self.gameMngr = gameMngr |
||
43 | self._cmd = gameMngr.cmdPool |
||
44 | |||
45 | def cmd(self, obj): |
||
46 | return self._cmd[obj.type] |
||
47 | |||
48 | def new(self, type): |
||
49 | obj = IDataHolder() |
||
50 | self._cmd[type].init(obj) |
||
51 | return obj |
||
52 | |||
53 | def init(self, obj): |
||
54 | # call superclass |
||
55 | pass |
||
56 | # define new attributes |
||
57 | obj.oid = Const.OID_NONE |
||
58 | obj.type = self.typeID |
||
59 | obj.owner = Const.OID_NONE |
||
60 | obj.compOf = Const.OID_NONE |
||
61 | obj.name = u'Unnamed' |
||
62 | # not needed |
||
63 | # obj.accRights = {} |
||
64 | |||
65 | def getReferences(self, tran, obj): |
||
66 | return None |
||
67 | |||
68 | def upgrade(self, tran, obj): |
||
69 | # call update method |
||
70 | try: |
||
71 | self.cmd(obj).update(tran, obj) |
||
72 | except: |
||
73 | log.warning("Cannot execute update method on", obj.oid) |
||
74 | refObj = self.new(obj.type) |
||
75 | new = refObj.__dict__.keys() |
||
76 | old = obj.__dict__.keys() |
||
77 | changed = 0 |
||
78 | # change attributes |
||
79 | # remove old |
||
80 | for attr in old: |
||
81 | if attr in new: |
||
82 | new.remove(attr) |
||
83 | else: |
||
84 | log.debug('IObject', 'Upgrade - del', obj.oid, obj.type, attr) |
||
85 | delattr(obj, attr) |
||
86 | changed = 1 |
||
87 | # set new |
||
88 | for attr in new: |
||
89 | log.debug('IObject', 'Upgrade - new', obj.oid, obj.type, attr) |
||
90 | setattr(obj, attr, getattr(refObj, attr)) |
||
91 | changed = 1 |
||
92 | |||
93 | def update(self, tran, obj): |
||
94 | pass |
||
95 | |||
96 | def loadDOMAttrs(self, obj, elem): |
||
97 | for index in xrange(0, elem.attributes.length): |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
![]() |
|||
98 | attr = elem.attributes.item(index) |
||
99 | if hasattr(obj, attr.nodeName): |
||
100 | attrType = type(getattr(obj, attr.nodeName)) |
||
101 | if attrType == types.IntType: |
||
102 | value = int(attr.nodeValue) |
||
103 | elif attrType == types.FloatType: |
||
104 | value = float(attr.nodeValue) |
||
105 | elif attrType == types.UnicodeType: |
||
106 | value = attr.nodeValue |
||
107 | elif attrType == types.StringType: |
||
108 | value = attr.nodeValue |
||
109 | else: |
||
110 | raise 'Unsupported attribute type %s' % attrType |
||
111 | setattr(obj, attr.nodeName, value) |
||
112 | else: |
||
113 | raise GameException('Unsupported attribute %s' % attr.nodeName) |
||
114 | |||
115 | @public(Const.AL_INFO) |
||
116 | def getInfo(self, tran, obj): |
||
117 | return obj |
||
118 | |||
119 | @public(Const.AL_INFO) |
||
120 | def get(self, tran, obj): |
||
121 | return self.cmd(obj).getInfo(tran, obj) |
||
122 | |||
123 | @public(Const.AL_NONE) |
||
124 | def getPublicInfo(self, tran, obj): |
||
125 | result = IDataHolder() |
||
126 | result.oid = obj.oid |
||
127 | return result |
||
128 | |||
129 | @public(Const.AL_ADMIN) |
||
130 | def set(self, tran, obj, attr, value): |
||
131 | if hasattr(obj, attr): |
||
132 | setattr(obj, attr, value) |
||
133 | return 1 |
||
134 | raise GameException('No such attribute.') |
||
135 | |||
136 | |||
137 | ## messaging api |
||
138 | @public(Const.AL_NONE) |
||
139 | def sendMsg(self, tran, obj, message): |
||
140 | if tran.session.cid != Const.OID_ADMIN: |
||
141 | message["sender"] = tran.session.nick |
||
142 | message["senderID"] = tran.session.cid |
||
143 | # check attributes |
||
144 | if "forum" not in message: |
||
145 | raise GameException("Forum not specified.") |
||
146 | if message["forum"] not in self.forums: |
||
147 | raise GameException("No such forum.") |
||
148 | if "topic" not in message: |
||
149 | raise GameException("Topic not specified.") |
||
150 | if "data" not in message and "text" not in message: |
||
151 | raise GameException("Text or structured data not specified.") |
||
152 | # check permissions |
||
153 | if tran.session.cid != Const.OID_ADMIN and \ |
||
154 | not self.canSendMsg(tran, obj, message["senderID"], message["forum"]): |
||
155 | raise SecurityException("You cannot send message to this entity.") |
||
156 | # |
||
157 | message["recipient"] = obj.name |
||
158 | message["recipientID"] = obj.oid |
||
159 | # send message |
||
160 | return tran.gameMngr.msgMngr.send(tran.gameMngr.gameID, obj.oid, message) |
||
161 | |||
162 | @public(Const.AL_ADMIN) |
||
163 | def sendAdminMsg(self, tran, obj, message): |
||
164 | # check attributes |
||
165 | if "forum" not in message: |
||
166 | raise GameException("Forum not specified.") |
||
167 | if message["forum"] not in self.forums: |
||
168 | raise GameException("No such forum.") |
||
169 | if "topic" not in message: |
||
170 | raise GameException("Topic not specified.") |
||
171 | if "data" not in message and "text" not in message: |
||
172 | raise GameException("Text or structured data not specified.") |
||
173 | # |
||
174 | message["recipient"] = obj.name |
||
175 | message["recipientID"] = obj.oid |
||
176 | # send message |
||
177 | return tran.gameMngr.msgMngr.send(tran.gameMngr.gameID, obj.oid, message) |
||
178 | |||
179 | @public(Const.AL_NONE) |
||
180 | def getMsgs(self, tran, obj, lastID = -1): |
||
181 | if not self.canGetMsgs(tran, obj, tran.session.cid): |
||
182 | raise SecurityException("You cannot read messages of this entity.") |
||
183 | # get messages |
||
184 | return tran.gameMngr.msgMngr.get(tran.gameMngr.gameID, obj.oid, lastID) |
||
185 | |||
186 | @public(Const.AL_NONE) |
||
187 | def deleteMsgs(self, tran, obj, ids): |
||
188 | if not self.canManageMsgs(tran, obj, tran.session.cid): |
||
189 | raise SecurityException("You cannot manage messages of this entity.") |
||
190 | # get messages |
||
191 | return tran.gameMngr.msgMngr.delete(tran.gameMngr.gameID, obj.oid, ids) |
||
192 | |||
193 | @public(Const.AL_ADMIN) |
||
194 | def deleteOldMsgs(self, tran, obj): |
||
195 | for forum in self.forums: |
||
196 | tran.gameMngr.msgMngr.deleteOld(tran.gameMngr.gameID, obj.oid, forum, maxAge = self.forums[forum]) |
||
197 | |||
198 | def canSendMsg(self, tran, obj, oid, forum): |
||
199 | return 0 |
||
200 | |||
201 | def canGetMsgs(self, tran, obj, oid): |
||
202 | return oid == obj.oid |
||
203 | |||
204 | def canManageMsgs(self, tran, obj, oid): |
||
205 | return oid == obj.oid or oid == Const.OID_ADMIN |
||
206 | |||
207 | def getMailboxName(self, tran, obj): |
||
208 | return (tran.gameMngr.gameID, obj.oid) |
||
209 |