1 | #!/usr/bin/env python2 |
||
2 | # |
||
3 | # Copyright 2001 - 2016 Ludek Smid [http://www.ospace.net/] |
||
4 | # |
||
5 | # This file is part of Outer Space. |
||
6 | # |
||
7 | # Outer Space is free software; you can redistribute it and/or modify |
||
8 | # it under the terms of the GNU General Public License as published by |
||
9 | # the Free Software Foundation; either version 2 of the License, or |
||
10 | # (at your option) any later version. |
||
11 | # |
||
12 | # Outer Space is distributed in the hope that it will be useful, |
||
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
15 | # GNU General Public License for more details. |
||
16 | # |
||
17 | # You should have received a copy of the GNU General Public License |
||
18 | # along with Outer Space; if not, write to the Free Software |
||
19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
||
20 | # |
||
21 | |||
22 | # tweak PYTHONPATH |
||
23 | import sys, string, re |
||
24 | import os |
||
25 | from optparse import OptionParser |
||
26 | baseDir = os.path.abspath(os.path.dirname(__file__)) |
||
27 | sys.path.insert(0, os.path.join(baseDir, '..', 'server', "lib")) |
||
28 | |||
29 | from igeclient.IClient import IClient |
||
30 | import pprint, traceback |
||
31 | from getpass import getpass |
||
32 | from code import InteractiveConsole |
||
33 | from ige.ospace import Const |
||
34 | import time |
||
35 | |||
36 | #not race specific: |
||
37 | levelTechs = {1: [ |
||
38 | 1000, 1100, 1101, 1102, 1104, 1106, 1107, 1110, 1112, |
||
39 | 1400, 1401, 1402, 1403, 1404, 1405, |
||
40 | 1500, 1510, 1511, |
||
41 | 1800, 1801, 1802, 1803, |
||
42 | ], |
||
43 | 2: [ |
||
44 | 1105, 1111, |
||
45 | 2001, 2006, |
||
46 | 2400, 2401, 2403, 2404, 2405, 2406, 2407, 2408, 2409, 2410, |
||
47 | 2801, 2802, 2803, |
||
48 | ], |
||
49 | 3: [ |
||
50 | 3000, 3010, 3013, |
||
51 | 3401, 3402, 3403, 3404, 3405, 3406, 3407, 3409, 3410, |
||
52 | 3450, 3451, |
||
53 | 3800, 3802, |
||
54 | ], |
||
55 | 4: [ |
||
56 | 4000, 4004, 4005, |
||
57 | ], |
||
58 | 5: [ |
||
59 | 5000, 5001, 5002, |
||
60 | 5800, 5801, 5802, 5803, |
||
61 | ], |
||
62 | 6: [ |
||
63 | 6000, 6001, 6005, 6025, |
||
64 | ], |
||
65 | 99: [ |
||
66 | 99001, 99002, 99003, 99004, |
||
67 | ]} |
||
68 | |||
69 | #race specific: |
||
70 | levelTechsRaces = { |
||
71 | 1: {'B': [], 'H': [], 'C': []}, |
||
72 | 2: { |
||
73 | 'B': [2003, 2005, 2007, 2804, 2805], |
||
74 | 'H': [2000, 2004], |
||
75 | 'C': [2002, 2004]}, |
||
76 | 3: { |
||
77 | 'B': [3001, 3003, 3007, 3008, 3412, 3420, 3421, 3452, 3454, 3803, ], |
||
78 | 'H': [3002, 3004, 3006, 3009, 3408, 3411, 3453, 3455, 3803, ], |
||
79 | 'C': [3001, 3005, 3006, 3411, 3453, 3456, ]}, |
||
80 | 4: { |
||
81 | 'B': [4003, 4006, 4008, 4400, 4401, 4402, 4403, 4404, 4405, 4406, 4458, 4460, 4476, 4502, 4504, ], |
||
82 | 'H': [4002, 4007, 4008, 4009, 4010, 4407, 4408, 4409, 4410, 4411, 4412, 4413, 4459, 4461, 4477, 4479, 4480, 4500, 4503, ], |
||
83 | 'C': [4001, 4006, 4007, 4414, 4415, 4416, 4417, 4418, 4419, 4420, 4459, 4462, 4477, 4479, 4501, 4503, ]}, |
||
84 | 5: { |
||
85 | 'B': [5400, 5401, 5402, 5403, 5404, 5405, 5406, 5007, 5431, 5433, 5465, 5467, 5470, 5475, 5503, 5504, 5508, 5805, 5808], |
||
86 | 'H': [5003, 5004, 5005, 5008, 5408, 5409, 5410, 5411, 5412, 5413, 5414, 5430, 5434, 5466, 5468, 5471, 5474, 5501, 5502, 5507, 5804, 5807], |
||
87 | 'C': [5006, 5416, 5417, 5418, 5419, 5420, 5421, 5432, 5435, 5466, 5469, 5472, 5473, 5476, 5505, 5506, 5806]}, |
||
88 | 6: { |
||
89 | 'B': [6200, 6201, 6202, 6203, 6204, 6205, 6220, 6221, 6222, 6241, ], |
||
90 | 'H': [6100, 6101, 6102, 6103, 6104, 6105, 6120, 6121, 6140, 6141, 6160, ], |
||
91 | 'C': [6301, 6302, 6303, 6304, 6305, 6306, 6320, 6321, 6322, 6323, 6340, 6360, ] |
||
92 | }, |
||
93 | 99: {'B': [], 'H': [], 'C': []}, |
||
94 | } |
||
95 | |||
96 | advTechLevel = { |
||
97 | 1: {}, |
||
98 | 2: {"B" : 1990, "H" : 1991, "C" : 1992}, |
||
99 | 3: {"B" : 2990, "H" : 2991, "C" : 2992}, |
||
100 | 4: {"B" : 3990, "H" : 3991, "C" : 3992}, |
||
101 | 5: {"B" : 4990, "H" : 4991, "C" : 4992}, |
||
102 | 6: {"B" : 5990, "H" : 5991, "C" : 5992}, |
||
103 | 99: {} |
||
104 | } |
||
105 | |||
106 | def cleanupBadFleets(): |
||
107 | un = s.getInfo(1) |
||
108 | delete = [] |
||
109 | #search by system rather than by player; there is no galaxy list of playerIDs |
||
110 | for galaxyID in un.galaxies: |
||
111 | galaxy = s.getInfo(galaxyID) |
||
112 | for systemID in galaxy.systems: |
||
113 | system = s.getInfo(systemID) |
||
114 | for fleetID in system.fleets: |
||
115 | fleet = s.getInfo(fleetID) |
||
116 | owner = s.getInfo(fleet.owner) |
||
117 | if not owner.galaxies: |
||
118 | delete.append((fleetID,systemID,fleet.owner,0)) |
||
119 | if owner.galaxies[0] != galaxyID: |
||
120 | delete.append((fleetID,systemID,fleet.owner,1)) |
||
121 | for row in delete: |
||
122 | if row[3]: |
||
123 | print "Deleting",row[0],"- owner not in fleet's galaxy" |
||
124 | else: |
||
125 | print "Deleting",row[0],"- owner not in a galaxy" |
||
126 | s.disbandFleet(row[0]) |
||
127 | return |
||
128 | |||
129 | |||
130 | def msgHandler(id, data): |
||
131 | if id >= 0: |
||
132 | print 'Message', id, data |
||
133 | |||
134 | def getPlayer(name): |
||
135 | u = s.getInfo(1) |
||
136 | for playerID in u.players: |
||
137 | pl = s.getInfo(playerID) |
||
138 | if pl.name == name: |
||
139 | return pl |
||
140 | return None |
||
141 | |||
142 | def showPlayers(): |
||
143 | un = s.getInfo(1) |
||
144 | players = [] |
||
145 | aiPlayers = [] |
||
146 | for playerID in un.players: |
||
147 | player = s.getInfo(playerID) |
||
148 | if not player.type in Const.AI_PLAYER_TYPES: |
||
149 | players.append((playerID, player.name)) |
||
150 | else: |
||
151 | aiPlayers.append((playerID, player.name)) |
||
152 | |||
153 | |||
154 | |||
155 | print "List of current players:" |
||
156 | for pl in players: |
||
157 | print "%5d: %s" % pl |
||
158 | |||
159 | print "List of current AI players:" |
||
160 | for pl in aiPlayers: |
||
161 | print "%5d: %s" % pl |
||
162 | |||
163 | |||
164 | print "Press Enter to continue" |
||
165 | raw_input() |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
![]() |
|||
166 | |||
167 | def showGalaxies(): |
||
168 | un = s.getInfo(1) |
||
169 | galaxies = [] |
||
170 | for galaxyID in un.galaxies: |
||
171 | galaxy = s.getInfo(galaxyID) |
||
172 | galaxies.append((galaxyID, galaxy.name)) |
||
173 | |||
174 | |||
175 | |||
176 | print "List of current galaxies:" |
||
177 | for gal in galaxies: |
||
178 | print "%5d: %s" % gal |
||
179 | |||
180 | |||
181 | |||
182 | def setCurrentObject(): |
||
183 | objId = raw_input("oid: ") |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
184 | newObjID = 0 |
||
185 | try: |
||
186 | newObjID = int(objId) |
||
187 | except: |
||
188 | print "Invalid object" |
||
189 | |||
190 | return newObjID |
||
191 | |||
192 | def initDevelTesting(objID): |
||
193 | levels = 6 |
||
194 | resources = 8 |
||
195 | |||
196 | race = string.upper(raw_input("race: ")) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
197 | if not (race=='b' or race=='B' or race=='c' or race=='C' or race =='h' or race =='H'): |
||
198 | print "Invalid race" |
||
199 | return objID |
||
200 | |||
201 | for level in range(2,levels+1): |
||
202 | advanceLevelRace(objID,level,race) |
||
203 | for level in range(1,levels+1): |
||
204 | giveTechsNum(objID,level) |
||
205 | giveTechsNum(objID,99) |
||
206 | for stratResID in range(1,resources+1): |
||
207 | giveStratResNum(objID,stratResID,50) |
||
208 | |||
209 | return objID |
||
210 | |||
211 | def giveTechs(objID): |
||
212 | lvl = raw_input("level: ") |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
213 | level = 0 |
||
214 | try: |
||
215 | level = int(lvl) |
||
216 | except: |
||
217 | print "Invalid level" |
||
218 | return objId |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
219 | |||
220 | if level > 6 and not level == 99: |
||
221 | print "Invalid level" |
||
222 | return objId |
||
223 | giveTechsNum(objID,level) |
||
224 | |||
225 | def giveTechsNum(objID,level): |
||
226 | player = s.getInfo(objID) |
||
227 | plTechs = player.techs |
||
228 | for techId in levelTechs[level]: |
||
229 | plTechs[techId] = 5 |
||
230 | |||
231 | if len(player.race) > 0: |
||
232 | print "setting race dependent techs" |
||
233 | for techId in levelTechsRaces[level][player.race]: |
||
234 | plTechs[techId] = 5 |
||
235 | |||
236 | s.set(objID, "techs", plTechs) |
||
237 | print "Techs at level %d added to player %d." % (level, objID) |
||
238 | return objID |
||
239 | |||
240 | def giveTech(objID): |
||
241 | tid = raw_input("techId: ") |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
242 | try: |
||
243 | techId = int(tid) |
||
244 | except: |
||
245 | print "Invalid techId" |
||
246 | return objID |
||
247 | |||
248 | player = s.getInfo(objID) |
||
249 | plTechs = player.techs |
||
250 | try: |
||
251 | plTechs[techId] = 5 |
||
252 | except: |
||
253 | print "Invalid techId" |
||
254 | return objID |
||
255 | |||
256 | s.set(objID, "techs", plTechs) |
||
257 | print "Tech %d added to player %d." % (techId, objID) |
||
258 | return objID |
||
259 | |||
260 | def advanceLevel(objID): |
||
261 | lvl = raw_input("level: ") |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
262 | try: |
||
263 | level = int(lvl) |
||
264 | except: |
||
265 | print "Invalid level" |
||
266 | return objID |
||
267 | |||
268 | if level > 6 or level < 2: |
||
269 | print "Invalid level" |
||
270 | return objID |
||
271 | race = string.upper(raw_input("race: ")) |
||
272 | if not (race=='b' or race=='B' or race=='c' or race=='C' or race =='h' or race =='H'): |
||
273 | print "Invalid race" |
||
274 | return objID |
||
275 | advanceLevelRace(objID,level) |
||
276 | |||
277 | def advanceLevelRace(objID,level,race): |
||
278 | player = s.getInfo(objID) |
||
279 | plTechs = player.techs |
||
280 | plTechs[advTechLevel[level][race]] = 5 |
||
281 | |||
282 | s.set(objID, "techs", plTechs) |
||
283 | s.set(objID, "techLevel", level) |
||
284 | s.set(objID, "race", race) |
||
285 | print "Tech %d added, techLevel advance to %d to player %d." % (advTechLevel[level][race], level, objID) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
286 | return objID |
||
287 | |||
288 | def promoteToImperator(objID): |
||
289 | galID = raw_input("galaxy id: ") |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
290 | try: |
||
291 | galaxyID = int(galID) |
||
292 | except: |
||
293 | print "Invalid galaxy id" |
||
294 | return objID |
||
295 | |||
296 | s.set(objID, "imperator", 3) |
||
297 | s.set(galaxyID, "imperator", objID) |
||
298 | print "Galaxy %d has now imperator %d." % (galaxyID, objID) |
||
299 | return objID |
||
300 | |||
301 | def giveFame(objID): |
||
302 | numFame = raw_input("Amount of Fame: ") |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
303 | try: |
||
304 | numberFame = int(numFame) |
||
305 | except: |
||
306 | print "Not a number" |
||
307 | return objID |
||
308 | player = s.getInfo(objID) |
||
309 | if not hasattr(player,'pirateFame'): |
||
310 | print "Object is not a pirate" |
||
311 | return objID |
||
312 | newFame = player.pirateFame + numberFame |
||
313 | s.set(objID, "pirateFame", newFame) |
||
314 | print "Player %d now has %d fame" % (objID, newFame) |
||
315 | |||
316 | def giveStratRes(objID): |
||
317 | resID = raw_input("strategy resource ('a' for all resources): ") |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
318 | if not (resID == 'a'): |
||
319 | try: |
||
320 | stratResID = int(resID) |
||
321 | except: |
||
322 | print "Invalid strategy resource" |
||
323 | return objID |
||
324 | |||
325 | qty = raw_input("qty: ") |
||
326 | try: |
||
327 | quantity = int(qty) |
||
328 | except: |
||
329 | print "Invalid quantity" |
||
330 | return objID |
||
331 | |||
332 | if (resID == 'a'): |
||
333 | for stratResID in range(1,9): |
||
334 | giveStratResNum(objID,stratResID,quantity) |
||
335 | else: |
||
336 | giveStratResNum(objID,stratResID,quantity) |
||
0 ignored issues
–
show
|
|||
337 | return objID |
||
338 | |||
339 | def giveStratResNum(objID,stratResID,quantity): |
||
340 | plQty = 0 |
||
341 | player = s.getInfo(objID) |
||
342 | if stratResID in player.stratRes: |
||
343 | plQty = player.stratRes[stratResID] |
||
344 | |||
345 | stratRes = player.stratRes |
||
346 | stratRes[stratResID] = plQty + quantity |
||
347 | s.set(objID, "stratRes", stratRes) |
||
348 | print "Player %d now has %d pieces of %d." % (objID, stratRes[stratResID], stratResID) |
||
349 | |||
350 | def createGalaxy(): |
||
351 | universe = 1 |
||
352 | print "Creating new galaxy...please specify these parameters. Normal galaxy positions are multiples of 100." |
||
353 | name = raw_input("Galaxy Name: ") |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
354 | gal_type = raw_input("Galaxy Type: ") |
||
355 | s.createNewSubscribedGalaxy(universe, name, gal_type, []) |
||
356 | |||
357 | def startGalaxy(): |
||
358 | showGalaxies() |
||
359 | objId = raw_input("oid: ") |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
360 | newObjID = 0 |
||
361 | try: |
||
362 | newObjID = int(objId) |
||
363 | except: |
||
364 | print "Invalid object" |
||
365 | un = s.getInfo(1) |
||
366 | galaxyObj = 0 |
||
367 | print newObjID |
||
368 | for galaxyID in un.galaxies: |
||
369 | print galaxyID |
||
370 | if galaxyID==newObjID: |
||
371 | galaxyObj = newObjID |
||
372 | if galaxyObj == 0: |
||
373 | print "Not a galaxy" |
||
374 | else: |
||
375 | s.enableTime(galaxyObj,1) |
||
376 | print "Galaxy will start on next turn process" |
||
377 | |||
378 | def deleteGalaxy(): |
||
379 | showGalaxies() |
||
380 | print "Choose a galaxy to delete." |
||
381 | objId = raw_input("oid: ") |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
382 | newObjID = 0 |
||
383 | try: |
||
384 | newObjID = int(objId) |
||
385 | except: |
||
386 | print "Invalid object" |
||
387 | un = s.getInfo(1) |
||
388 | galaxyObj = 0 |
||
389 | print newObjID |
||
390 | for galaxyID in un.galaxies: |
||
391 | if galaxyID==newObjID: |
||
392 | galaxyObjID = newObjID |
||
393 | if galaxyObjID == 0: |
||
0 ignored issues
–
show
|
|||
394 | print "Not a galaxy" |
||
395 | else: |
||
396 | galaxy = s.getInfo(galaxyObjID) |
||
397 | print "Please confirm that you want to delete", galaxy.name |
||
398 | ok = raw_input("Y/N: "); |
||
399 | if string.upper(ok) == "Y": |
||
400 | s.delete(galaxyObjID) |
||
401 | print "Galaxy deleted" |
||
402 | |||
403 | def showObj(objID): |
||
404 | try: |
||
405 | obj = s.getInfo(objID) |
||
406 | objstr = repr(obj) |
||
407 | #insanely complex regex to chunk {data} and [data] parts during split by ,'s |
||
408 | objarr = re.findall("[^,\{\]]*(?:\{[^\}]*[\}\{]),?|[^,\{\]]*(?:\[[^\]]*[\]\[]),?|[^,\}\]]+,?",objstr) |
||
409 | for line in objarr: |
||
410 | print line |
||
411 | except: |
||
412 | print "Cannot get object",objID |
||
413 | |||
414 | def showMenu(objID): |
||
415 | |||
416 | print "----- OSpace admin console menu -----" |
||
417 | print "Current object: %s" % objID |
||
418 | |||
419 | print "1. Set current object 10. Create Galaxy" |
||
420 | print "2. Show Players 11. Start Galaxy Time (does not need Obj set)" |
||
421 | print "3. Show Galaxies 12. Delete Galaxy (does not need Obj set)" |
||
422 | print "4. Advance to level 13. Init Developer race (all techs, 50 each strat res)" |
||
423 | print "5. Make imperator 14. Give Fame to a Pirate Player" |
||
424 | print "6. Give particular tech " |
||
425 | print "7. Give techs " |
||
426 | print "8. Give Strat Res " |
||
427 | print "9. Finish prod queue " |
||
428 | |||
429 | print "T. Process turn R. Process X turns" |
||
430 | print "C. Interactive console I. Object Info" |
||
431 | |||
432 | print "Ctrl+Z to End" |
||
433 | |||
434 | |||
435 | def processTurns(): |
||
436 | numT = raw_input("Number of turns: ") |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
437 | try: |
||
438 | num = int(numT) |
||
439 | except: |
||
440 | print "invalid number of turns" |
||
441 | s.processTurns(num) |
||
442 | |||
443 | def finishProdQueue(objId): |
||
444 | p = s.get(objId) |
||
445 | for i in p.prodQueue: |
||
446 | i.currProd = 38400 |
||
447 | s.set(p.oid, "prodQueue", p.prodQueue) |
||
448 | |||
449 | def processMenu(inp, objId, s): |
||
450 | if inp == "2": |
||
451 | showPlayers() |
||
452 | elif inp == "1": |
||
453 | return setCurrentObject() |
||
454 | elif inp == "7": |
||
455 | giveTechs(objId) |
||
456 | elif inp == "6": |
||
457 | giveTech(objId) |
||
458 | elif inp == "4": |
||
459 | advanceLevel(objId) |
||
460 | elif inp == "3": |
||
461 | showGalaxies() |
||
462 | elif inp == "5": |
||
463 | promoteToImperator(objId) |
||
464 | elif inp == "8": |
||
465 | giveStratRes(objId) |
||
466 | elif inp == "9": |
||
467 | finishProdQueue(objId) |
||
468 | elif inp == "10": |
||
469 | createGalaxy() |
||
470 | elif inp == "11": |
||
471 | startGalaxy() |
||
472 | elif inp == "12": |
||
473 | deleteGalaxy() |
||
474 | elif inp == "13": |
||
475 | initDevelTesting(objID) |
||
476 | elif inp == "14": |
||
477 | giveFame(objID) |
||
478 | elif string.upper(inp) == "I": |
||
479 | showObj(objID) |
||
480 | elif string.upper(inp) == "R": |
||
481 | processTurns() |
||
482 | elif string.upper(inp) == "T": |
||
483 | s.processTurn() |
||
484 | elif string.upper(inp) == "C": |
||
485 | console = InteractiveConsole(locals()) |
||
486 | console.interact() |
||
487 | elif string.upper(inp) == "CLEANUPFLEETS": |
||
488 | console = cleanupBadFleets() |
||
489 | |||
490 | return objId |
||
491 | |||
492 | # parse command line arguments |
||
493 | parser = OptionParser(usage = "usage: %prog [options]") |
||
494 | parser.add_option("", "--configdir", dest = "configDir", |
||
495 | metavar = "DIRECTORY", default = os.path.join(os.path.expanduser("~"), ".outerspace"), |
||
496 | help = "Override default configuration directory", |
||
497 | ) |
||
498 | options, args = parser.parse_args() |
||
499 | |||
500 | #s = IClient('ospace.net:9080', None, msgHandler, None, 'IClient/osc') |
||
501 | s = IClient('localhost:9080', None, msgHandler, None, 'IClient/osc') |
||
502 | |||
503 | |||
504 | # get admin login from <configDir>/token |
||
505 | password = open(os.path.join(options.configDir, "token"), "r").read() |
||
506 | s.connect() |
||
507 | s.login('Alpha', 'admin', password) |
||
508 | s.selectAdmin() |
||
509 | |||
510 | try: |
||
511 | objID = 0 |
||
512 | while True: |
||
513 | showMenu(objID) |
||
514 | objID = processMenu(raw_input(), objID, s) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
515 | except EOFError: |
||
516 | pass |
||
517 | |||
518 | s.logout() |
||
519 |