osclient_tui.processMenu()   F
last analyzed

Complexity

Conditions 20

Size

Total Lines 42
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 20
eloc 41
nop 3
dl 0
loc 42
rs 0
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like osclient_tui.processMenu() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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
    print
154
    print
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
    print
164
    print "Press Enter to continue"
165
    raw_input()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable raw_input does not seem to be defined.
Loading history...
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
    print
175
    print
176
    print "List of current galaxies:"
177
    for gal in galaxies:
178
        print "%5d: %s" % gal
179
180
    print
181
182
def setCurrentObject():
183
    objId = raw_input("oid: ")
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable raw_input does not seem to be defined.
Loading history...
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
The variable raw_input does not seem to be defined.
Loading history...
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
The variable raw_input does not seem to be defined.
Loading history...
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
The variable objId does not seem to be defined.
Loading history...
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
The variable raw_input does not seem to be defined.
Loading history...
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
The variable raw_input does not seem to be defined.
Loading history...
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
The variable advTechLevel does not seem to be defined.
Loading history...
286
    return objID
287
288
def promoteToImperator(objID):
289
    galID = raw_input("galaxy id: ")
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable raw_input does not seem to be defined.
Loading history...
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
The variable raw_input does not seem to be defined.
Loading history...
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
The variable raw_input does not seem to be defined.
Loading history...
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
introduced by
The variable stratResID does not seem to be defined in case BooleanNotNode on line 318 is False. Are you sure this can never be the case?
Loading history...
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
The variable raw_input does not seem to be defined.
Loading history...
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
The variable raw_input does not seem to be defined.
Loading history...
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
The variable raw_input does not seem to be defined.
Loading history...
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
introduced by
The variable galaxyObjID does not seem to be defined for all execution paths.
Loading history...
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
    print
416
    print "----- OSpace admin console menu -----"
417
    print "Current object: %s" % objID
418
    print
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
    print
429
    print "T. Process turn        R. Process X turns"
430
    print "C. Interactive console     I. Object Info"
431
    print
432
    print "Ctrl+Z to End"
433
    print
434
435
def processTurns():
436
    numT = raw_input("Number of turns: ")
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable raw_input does not seem to be defined.
Loading history...
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
The variable raw_input does not seem to be defined.
Loading history...
515
except EOFError:
516
       pass
517
518
s.logout()
519