Issues (229)

client-ai/ai_client.py (6 issues)

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
21
from igeclient import IClient, IClientDB
22
from ige.ospace import Const
23
from ige.ospace import Rules
24
from ige.IDataHolder import IDataHolder
25
import ige, gdata, osci, math, time
26
from ige import log
27
28
# module globals
29
cmdProxy = None
30
db = None
31
lastUpdate = -1
32
server = None
33
nonexistingObj = {}
34
options = None
35
36
def initialize(aServer, anOptions):
37
    global server, options
38
    server = aServer
39
    options = anOptions
40
    initCmdProxy()
41
42
def initCmdProxy():
43
    global cmdProxy, server
44
    if not cmdProxy:
45
        proxy = None
46
        if gdata.config.proxy.http != None:
47
            proxy = gdata.config.proxy.http
48
        cmdProxy = IClient.IClient(server, proxy, None, None, 'OSClient/%s' % ige.version.versionString)
49
50
## Authentication
51
52
def login(gameid, login, password):
53
    cmdProxy.connect()
54
    if cmdProxy.login(gameid, login, password):
55
        return 1
56
    return 0
57
58
def logout():
59
    global db, lastUpdate
60
    if cmdProxy and cmdProxy.logged:
61
        cmdProxy.logout()
62
    saveDB()
63
    db = None
64
    lastUpdate = -1
65
66
def saveDB():
67
    if db:
68
        log.message('OSClient', 'Saving database')
69
        db.save()
70
71
## Updater
72
73
def updateDatabase(clearDB = 0):
74
    try:
75
        return updateDatabaseUnsafe(clearDB)
76
    except:
77
        log.warning("Cannot update database")
78
    return updateDatabaseUnsafe(clearDB = 1, force = 1)
79
80
def updateDatabaseUnsafe(clearDB = 0, force = 0):
81
    """Update database by fetching data from the server."""
82
    global lastUpdate, nonexistingObj, db
83
    # get real turn
84
    result = cmdProxy.getIntroInfo(Const.OID_UNIVERSE)
85
    if not db:
86
        db = IClientDB.IClientDB(result.cid, result.turn, options.configDir, cmdProxy.gameID)
87
    if clearDB:
88
        db.clear()
89
    db.turn = result.turn
90
    #
91
    if db.turn <= lastUpdate and not force:
92
        return
93
    log.message('IClient', 'Updating...')
94
    lastUpdate = db.turn
95
    nonexistingObj.clear()
96
    current = 0
97
    max = 1
98
    # compute total objects to be fetched
99
    max += 6 # clear map, get messages, ...
100
    current += 1
101
    # delete selected objects
102
    # reset combatCounters
103
    for objID in db.keys():
104
        obj = db[objID]
105
        if hasattr(obj, "combatCounter"):
106
            obj.combatCounter = 0
107 View Code Duplication
        if not hasattr(obj, 'type'):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
108
            del db[objID]
109
        elif obj.type == Const.T_FLEET:
110
            del db[objID]
111
        elif hasattr(obj, 'owner') and obj.owner == db.playerID \
112
            and objID != db.playerID:
113
            # delete player's objects
114
            del db[objID]
115
        else:
116
            if hasattr(obj, "scanPwr"): obj.scanPwr = 0
117
            if hasattr(obj, "scannerPwr"): obj.scannerPwr = 0
118
    # update player
119
    db[db.playerID] = get(db.playerID)
120
    player = db[db.playerID]
121
    # update from scanner's map
122
    scannerMap = cmdProxy.getScannerMap(db.playerID)
123
    for objID in scannerMap:
124
        db[objID] = scannerMap[objID]
125
    # update player's planets and fleets
126
    for obj in cmdProxy.multiGetInfo(1, player.planets[:] + player.fleets[:]):
127
        db[obj.oid] = obj
128
    # finished
129
    log.message('IClient', 'Update finished.')
130
131
## Basic functions
132
133 View Code Duplication
def get(objID, forceUpdate = 0, noUpdate = 0, canBePublic = 1, publicOnly = 0):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
134
    global nonexistingObj
135
    if nonexistingObj.has_key(objID) and not forceUpdate:
136
        return None
137
    if noUpdate:
138
        return db.get(objID, None)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable db does not seem to be defined.
Loading history...
139
    if (db.needsUpdate(objID) or forceUpdate) and not publicOnly:
140
        try:
141
            db[objID] = cmdProxy.getInfo(objID)
142
        except ige.SecurityException:
143
            if canBePublic:
144
                db[objID] = cmdProxy.getPublicInfo(objID)
145
            else:
146
                return db.get(objID, None)
147
        except ige.NoSuchObjectException:
148
            if db.has_key(objID):
149
                del db[objID]
150
            nonexistingObj[objID] = None
151
            return None
152
    if (db.needsUpdate(objID) or forceUpdate) and publicOnly: #for when the data you need is never anything but public
153
        try:
154
            db[objID] = cmdProxy.getPublicInfo(objID)
155
        except ige.NoSuchObjectException:
156
            if db.has_key(objID):
157
                del db[objID]
158
            nonexistingObj[objID] = None
159
            return None
160
    return db[objID]
161
162
def updateIDs(objIDs):
163
    delete = objIDs[:]
164
    for obj in cmdProxy.multiGetInfo(1, objIDs):
165
        db[obj.oid] = obj
166
        delete.remove(obj.oid)
167
    for objID in delete:
168
        if db.has_key(objID):
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable db does not seem to be defined.
Loading history...
169
            del db[objID]
170
171 View Code Duplication
def getRelationTo(objID):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
172
    obj = getPlayer()
173
    if obj.oid == objID:
174
        return Const.REL_UNITY
175
    if objID == Const.OID_NONE:
176
        return Const.REL_UNDEF
177
    dipl = obj.diplomacyRels.get(objID, None)
178
    if dipl:
179
        return dipl.relation
180
    else:
181
        return obj.defaultRelation
182
183
def getTurn():
184
    return db.turn
185
186
def getFullTechInfo(techID):
187
    player = db[db.playerID]
188
    return Rules.techs[techID]
189
190
def getTechInfo(techID):
191
    player = db[db.playerID]
192
    tech = Rules.techs[techID]
193
    # player possess this technology
194
    if player.techs.has_key(techID):
195
        return tech
196
197
    if tech.fullInfo:
198
        return tech
199
200
    # player can research this technology
201
    canResearch = 1
202
    if player.race not in tech.researchRaces:
203
        canResearch = 0
204
    for tmpTechID, improvement in tech.researchRequires:
205
        if not player.techs.has_key(tmpTechID) or player.techs[tmpTechID] < improvement:
206
            canResearch = 0
207
            break
208
    for stratRes in tech.researchReqSRes:
209
        if player.stratRes.get(stratRes, 0) < 1:
210
            canResearch = 0
211
            break
212
    for tmpTechID in player.techs:
213
        if techID in Rules.techs[tmpTechID].researchDisables:
214
            canResearch = 0
215
            break
216
    if tech.level > player.techLevel:
217
        canResearch = 0
218
219
    if canResearch:
220
        result = IDataHolder()
221
        result.partialData = None
222
        for attr in ['name', 'isDiscovery', 'isStructure',
223
            'isProject', 'isShipEquip', 'isShipHull', 'researchMod',
224
            'researchTurns', 'textPreRsrch', 'researchRequires', 'subtype',
225
            "researchReqSRes", "researchDisables", "level", "researchRaces"]:
226
            setattr(result, attr, getattr(tech, attr))
227
        return result
228
    # player should know only basic params about tech
229
    result = IDataHolder()
230
    result.partialData = None
231
    for attr in ["name", "researchRequires", "subtype", "level", "researchRaces"]:
232
        setattr(result, attr, getattr(tech, attr))
233
    return result
234
235
def getAllTechIDs():
236
    return Rules.techs.keys()
237
238
def getPlayerID():
239
    return db.playerID
240
241
def getPlayer():
242
    return db[db.playerID]
243
244 View Code Duplication
def getDiplomacyWith(contactID):
0 ignored issues
show
This code seems to be duplicated in your project.
Loading history...
245
    obj = getPlayer()
246
    dipl = obj.diplomacyRels.get(contactID, None)
247
    if not dipl:
248
        # make default
249
        dipl = IDataHolder()
250
        dipl.type = Const.T_DIPLREL
251
        dipl.pacts = {
252
            Const.PACT_ALLOW_CIVILIAN_SHIPS: [Const.PACT_ACTIVE, Const.PACT_ALLOW_CIVILIAN_SHIPS]
253
        }
254
        dipl.relation = obj.defaultRelation
255
        dipl.relChng = 0
256
        dipl.lastContact = 0
257
        dipl.stats = None
258
        dipl.contactType = Const.CONTACT_NONE
259
        obj.diplomacyRels[playerID] = dipl
260
    return dipl
261
262