2 # -*- coding: utf-8 -*-
4 GalTacK networking - client-side universe bookkeeping.
6 # Copyright (C) 2007 Felix Rabe <public@felixrabe.textdriven.com>
7 # Copyright (C) 2007 Michael Carter
9 # Permission is hereby granted, free of charge, to any person obtaining a
10 # copy of this software and associated documentation files (the
11 # "Software"), to deal in the Software without restriction, including
12 # without limitation the rights to use, copy, modify, merge, publish,
13 # distribute, sublicense, and/or sell copies of the Software, and to permit
14 # persons to whom the Software is furnished to do so, subject to the
15 # following conditions:
17 # The above copyright notice and this permission notice shall be included
18 # in all copies or substantial portions of the Software.
20 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
25 # OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
26 # THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 # Recommended line length or text width: 75 characters.
33 from galtack
.net_client_base
import *
36 class GaltackClientPlayerTrackerMixin(GaltackClientBackCallerMixin
):
38 GaltackClient that keeps track of players.
41 def __init__(self
, *a
, **kw
):
42 super(GaltackClientPlayerTrackerMixin
, self
).__init
__(*a
, **kw
)
43 self
.player_info_dict
= {}
44 self
.player_ingame_info_dict
= {}
45 self
.register_command_callback("players", self
.__cmd
_players
)
46 self
.register_command_callback("start", self
.__cmd
_start
)
47 self
.register_command_callback("stop", self
.__cmd
_stop
)
49 def __cmd_players(self
, command
):
50 recv_players
= command
[3:]
51 self
.player_info_dict
= {}
52 for player
in recv_players
:
54 self
.player_info_dict
[s
[0]] = PlayerPlayersInfo(*s
)
56 def __cmd_start(self
, command
):
57 self
.player_ingame_info_dict
= {}
58 for player
in command
[3].split(';'):
60 self
.player_ingame_info_dict
[s
[0]] = PlayerStartInfo(*s
)
62 def __cmd_stop(self
, command
):
63 self
.player_ingame_info_dict
= {}
66 class GaltackClientGameTrackerMixin(GaltackClientBackCallerMixin
):
68 GaltackClient that keeps track of the game state (running or not).
71 def __init__(self
, *a
, **kw
):
72 super(GaltackClientGameTrackerMixin
, self
).__init
__(*a
, **kw
)
73 self
.game_running
= False
74 self
.register_command_callback("start", self
.__cmd
_start
)
75 self
.register_command_callback("stop", self
.__cmd
_stop
)
77 def __cmd_start(self
, command
):
78 self
.game_running
= True
80 def __cmd_stop(self
, command
):
81 self
.game_running
= False
84 class UniverseB64Data(object):
86 Core data structure representing the universe data encoded in Base64,
97 def __init__(self
, b64string
= None):
99 if b64string
is not None:
100 self
._raw
_data
= self
.__decode
(b64string
)
103 for line
in (li
.split("\t") for li
in self
._raw
_data
.split("\n")):
104 if line
[0] == "planet":
105 self
.planets
.append(PlanetB64Info(*line
[1:]))
106 if self
.options
is not None:
107 self
.planets
[-1].level_scale
= self
.options
.scale
109 if line
[0] == "user":
110 self
.users
.append(PlayerB64Info(*line
[1:]))
112 if line
[0] == "options":
113 self
.options
= OptionB64Info(*line
[1:])
115 if line
[0] == "version":
116 self
.version
= int(line
[1])
118 if len(line
) == 1 and line
[0] == "":
120 raise Exception, "unrecognized format"
122 def _reset_stuff(self
):
124 self
._version
_updated
= False
131 d
= UniverseB64Data()
132 d
._raw
_data
= copy
.copy(self
._raw
_data
)
133 d
._version
_updated
= copy
.copy(self
._version
_updated
)
134 d
.version
= copy
.copy(self
.version
)
135 d
.options
= copy
.copy(self
.options
)
136 d
.users
= map(copy
.copy
, self
.users
)
137 d
.planets
= map(copy
.copy
, self
.planets
)
140 def update(self
, b64string
):
141 self
._raw
_data
= self
.__decode
(b64string
)
143 for line
in (li
.split("\t") for li
in self
._raw
_data
.split("\n")):
144 if len(line
) == self
.LINE_LEN
["planet"]:
145 p
= self
.planets
[planet_index
]
146 for i
, field
in enumerate(line
[1:]):
147 if not field
: continue
152 raise Exception, "unrecognized format %r" % line
155 def __decode(b64string
):
156 return zlib
.decompress(base64
.b64decode(b64string
))
159 class GaltackClientUniverseTrackerMixin(GaltackClientBackCallerMixin
):
161 GaltackClient that keeps its idea of the GalTacK universe up-to-date.
164 def __init__(self
, *a
, **kw
):
165 super(GaltackClientUniverseTrackerMixin
, self
).__init
__(*a
, **kw
)
167 self
.register_command_callback("start", self
.__cmd
_start
)
168 self
.register_command_callback("delta", self
.__cmd
_delta
)
169 self
.register_command_callback("stop", self
.__cmd
_stop
)
173 return zlib
.decompress(base64
.b64decode(data
))
175 def __cmd_start(self
, command
):
176 if len(command
) < 4: return None
177 self
.players_start
= [l
.split(",") for l
in command
[3].split(";")]
178 if len(command
) < 6: return None
179 self
.u64data
= UniverseB64Data(command
[5])
182 def __cmd_delta(self
, command
):
183 if self
.u64data
is None:
184 print "whoops, no u64data"
186 self
.u64data
.update(command
[3])
188 def __cmd_stop(self
, command
):