2 # -*- coding: utf-8 -*-
4 GalTacK networking - code common to all the GalTacK networking.
6 Currently this consists of data structures.
8 # Copyright (C) 2007 Felix Rabe <public@felixrabe.textdriven.com>
9 # Copyright (C) 2007 Michael Carter
11 # Permission is hereby granted, free of charge, to any person obtaining a
12 # copy of this software and associated documentation files (the
13 # "Software"), to deal in the Software without restriction, including
14 # without limitation the rights to use, copy, modify, merge, publish,
15 # distribute, sublicense, and/or sell copies of the Software, and to permit
16 # persons to whom the Software is furnished to do so, subject to the
17 # following conditions:
19 # The above copyright notice and this permission notice shall be included
20 # in all copies or substantial portions of the Software.
22 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
27 # OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
28 # THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 # Recommended line length or text width: 75 characters.
35 class TableRowData(object):
37 Base class for rows of tables.
39 Actually, it is very easy to use. Take the *Info classes further down
40 this file as a starting point.
43 # COL_SPEC example to document the structure - override in derived
45 # (You can use TableRowData.build_col_spec_from_string() to build
46 # COL_SPEC and COL_SPEC_DICT automatically.)
53 "default": "No Name (default, optional)",
56 "name": "user_password",
58 "caption": "Password",
60 "default": "", # unset
65 "caption": "Logged In?",
72 # COL_SPEC_DICT example to document the structure - override in derived
74 # (You can use TableRowData.build_col_spec_dict() to build
75 # COL_SPEC_DICT automatically.)
77 "user_name": COL_SPEC
[0],
78 "user_password": COL_SPEC
[1],
79 "logged_in": COL_SPEC
[2],
83 def __init__(self
, *args
, **kwargs
):
85 Initialize in a user-friendly way.
88 TableRowData("Peter").user_name == "Peter"
89 TableRowData(user_name = "Peter")["user_name"] == "Peter"
92 for i
, arg
in enumerate(args
):
93 spec
= self
.COL_SPEC
[i
]
94 self
.__data
[spec
["name"]] = spec
["type"](arg
)
95 for spec
in self
.COL_SPEC
:
99 self
.__data
[n
] = t(kwargs
.pop(n
))
100 elif n
not in self
.__data
:
101 self
.__data
[n
] = t(spec
["default"])
102 super(TableRowData
, self
).__init
__(self
, **kwargs
)
106 Implement copy.copy(TableRowData_instance) properly.
108 row_data
= self
.__class
__()
109 for key
, value
in self
.__data
.iteritems():
110 row_data
[key
] = copy
.copy(value
)
114 def build_col_spec_from_string(string
):
116 Build COL_SPEC and COL_SPEC_DICT by parsing a string.
118 Return: (COL_SPEC, COL_SPEC_DICT)
121 TableRowData.build_col_spec_from_string(
123 user_name; str; User; No Name (default, optional)
124 user_password; str; (Password)
125 logged_in; bool; (Logged In?); False
127 ) == (TableRowData.COL_SPEC, TableRowData.COL_SPEC_DICT)
129 lines
= string
.strip().split("\n")
130 lines
= map(lambda line
:
131 map( lambda i
: i
.strip(), line
.split(";") ),
138 type = __builtins__
[line
[1]]
143 if caption
[0] == "(" and caption
[-1] == ")":
144 caption
= caption
[1:-1]
152 default
= type(eval(line
[-1]))
160 col_spec
.append(spec_dict
)
161 return (col_spec
, TableRowData
.build_col_spec_dict(col_spec
))
164 def build_col_spec_dict(col_spec
):
166 Build COL_SPEC_DICT from COL_SPEC.
168 Return: COL_SPEC_DICT
171 TableRowData.build_col_spec_dict(
172 TableRowData.COL_SPEC
173 ) == TableRowData.COL_SPEC_DICT
176 for spec
in col_spec
:
177 col_spec_dict
[spec
["name"]] = spec
180 def get_data_tuple(self
):
182 Get a tuple containing all the data.
185 for spec
in self
.COL_SPEC
:
186 tup
.append(self
.__data
[spec
["name"]])
189 def get_visible_data_tuple(self
):
191 Get a tuple containing all the visible data.
194 for i
, x
in enumerate(self
.get_tuple()):
195 if self
.COL_SPEC
[i
]["visible"] == True:
200 def get_col_types(cls
):
202 Get a tuple containing all the data types.
204 return tuple(s
["type"] for s
in cls
.COL_SPEC
)
207 def get_visible_col_types(cls
):
209 Get a tuple containing all the visible data types.
212 for i
, x
in enumerate(cls
.get_types()):
213 if cls
.COL_SPEC
[i
]["visible"] == True:
217 def __getitem__(self
, name
):
219 Make self["user_name"] and self[0] work.
226 spec
= self
.COL_SPEC
[i
]
227 return self
.__data
[spec
["name"]]
229 return self
.__data
[name
]
231 raise AttributeError, name
233 def __getattr__(self
, name
):
235 Make self.user_name work.
237 return self
.__getitem
__(name
)
239 def __setitem__(self
, name
, value
):
241 Make self["password"] (or self[1]) = "my0dear1secret" work.
248 spec
= self
.COL_SPEC
[i
]
249 self
.__data
[spec
["name"]] = spec
["type"](value
)
251 if name
not in self
.__data
:
252 raise AttributeError, "unknown field name '%s'" % name
253 self
.__data
[name
] = self
.COL_SPEC_DICT
[name
]["type"](value
)
255 def __setattr__(self
, name
, value
):
257 Make self.password = 'my0dear1secret' work.
259 if name
== "_TableRowData__data":
260 return super(TableRowData
, self
).__setattr
__(name
, value
)
261 return self
.__setitem
__(name
, value
)
265 Format this row of data for human eyes.
268 maxlen
= max(len(s
["caption"]) for s
in self
.COL_SPEC
)
269 for spec
in self
.COL_SPEC
:
270 lines
.append(("%%-%us%%r" % (maxlen
+ 2)) %
271 (spec
["caption"] + ":",
272 self
.__data
[spec
["name"]]))
274 return "\n".join(lines
)
277 class ServerInfo(TableRowData
):
279 Information about a GalTacK server.
282 COL_SPEC
, COL_SPEC_DICT
= TableRowData
.build_col_spec_from_string("""
283 bots_ok; bool; (Bots Ok)
286 version; str; Version
289 pwd_protected; bool; Protected
290 status; str; (Status)
291 addr; str; (IP Address)
292 port; int; (Port); 9031
293 secret; str; (Secret Hash)
294 passwd; str; (Password)
298 class UserInfo(TableRowData
):
300 Information about a GalTacK user.
303 COL_SPEC
, COL_SPEC_DICT
= TableRowData
.build_col_spec_from_string("""
306 passwd; str; Password
307 platform; str; Platform; linux2
308 version; str; Version; 1.2.0
312 class PlayerPlayersInfo(TableRowData
):
314 Information about a GalTacK player.
317 COL_SPEC
, COL_SPEC_DICT
= TableRowData
.build_col_spec_from_string("""
329 class PlayerStartInfo(TableRowData
):
331 In-game information about a GalTacK player.
334 COL_SPEC
, COL_SPEC_DICT
= TableRowData
.build_col_spec_from_string("""
342 class OptionB64Info(TableRowData
):
344 In-game, base64-encoded information about GalTacK "options".
347 COL_SPEC
, COL_SPEC_DICT
= TableRowData
.build_col_spec_from_string("""
357 class PlayerB64Info(TableRowData
):
359 In-game, base64-encoded information about a GalTacK player.
362 COL_SPEC
, COL_SPEC_DICT
= TableRowData
.build_col_spec_from_string("""
370 class PlanetB64Info(TableRowData
):
372 (In-game) information about a GalTacK planet.
375 COL_SPEC
, COL_SPEC_DICT
= TableRowData
.build_col_spec_from_string("""
377 x; int; X Position; 0
378 y; int; Y Position; 0
379 owner_num; int; Owner (Number); 0
380 prod; int; Production; 0
381 troops; int; Troops; 0
382 junk1; str; Junk 1; 0
383 junk2; str; Junk 2; 0
384 junk3; str; Junk 3; 0
385 junk4; str; Junk 4; 0
386 junk5; str; Junk 5; 0
387 junk6; str; Junk 6; 0
388 junk7; str; Junk 7; 0
389 junk8; str; Junk 8; 0
390 junk9; str; Junk 9; 0