1
+ import codecs
2
+ import sys
3
+
4
+ from PyQt5 .QtCore import QCoreApplication , QDateTime , QDir , QFileInfo
5
+ from PyQt5 .QtGui import QIcon
6
+ from PyQt5 .QtWidgets import QMessageBox
7
+
8
+ if "mobase" not in sys .modules :
9
+ import mock_mobase as mobase
10
+
11
+ class AGameGamePlugins (mobase .GamePlugins ):
12
+ def __init__ (self , organizer ):
13
+ #QMessageBox.information(None, "__init__", "__init__gp")
14
+ super (AGameGamePlugins , self ).__init__ ()
15
+ self .__organizer = organizer
16
+ self .__lastRead = None
17
+
18
+ def writePluginLists (self , pluginList ):
19
+ #QMessageBox.information(None, "writePluginLists", "writePluginLists")
20
+ if self .__lastRead == None :
21
+ return
22
+ with open (os .path .join (self .__organizer .profile ().absolutePath (), "plugins.txt" ), 'w' ) as pf :
23
+ with codecs .open (os .path .join (self .__organizer .profile ().absolutePath (), "loadorder.txt" ), 'w' , "utf-8" ) as lof :
24
+ pf .write ("# This file was automatically generated by Mod Organizer, but in Python!\n " )
25
+ lof .write ("# This file was automatically generated by Mod Organizer, but in Python!\n " )
26
+ sortedList = pluginList .pluginNames ()
27
+ sortedList .sort (key = lambda x : pluginList .priority (x ))
28
+ for pluginName in sortedList :
29
+ if pluginList .state (pluginName ) == 2 :
30
+ pf .write (pluginName )
31
+ pf .write ("\n " )
32
+ lof .write (pluginName )
33
+ lof .write ("\n " )
34
+ self .__lastRead = QDateTime .currentDateTime ()
35
+
36
+ def readPluginLists (self , pluginList ):
37
+ #QMessageBox.information(None, "readPluginLists", "readPluginLists")
38
+ pluginsPath = os .path .join (self .__organizer .profile ().absolutePath (), "plugins.txt" )
39
+ loadorderPath = os .path .join (self .__organizer .profile ().absolutePath (), "loadorder.txt" )
40
+
41
+ loadOrderIsNew = self .__lastRead == None or not QFileInfo (loadorderPath ).exists () or QFileInfo (loadorderPath ).lastModified () > self .__lastRead
42
+ pluginsIsNew = self .__lastRead == None or QFileInfo (pluginsPath ).lastModified () > self .__lastRead
43
+
44
+ if loadOrderIsNew or not pluginsIsNew :
45
+ self .__readLoadOrderList (pluginList , loadorderPath )
46
+ self .__readPluginList (pluginList , False )
47
+ else :
48
+ self .__readPluginList (pluginList , True )
49
+
50
+ self .__lastRead = QDateTime .currentDateTime ()
51
+
52
+ def __readLoadOrderList (self , pluginList , filePath ):
53
+ #QMessageBox.information(None, "__readLoadOrderList", "__readLoadOrderList")
54
+ try :
55
+ with codecs .open (filePath , "r" , "utf-8-sig" ) as file :
56
+ plugins = self .__organizer .managedGame ().primaryPlugins ()
57
+ plugins = [item .decode ("utf-8" ) for item in plugins ]
58
+ file .seek (0 , os .SEEK_END )
59
+ if file .tell () == 0 :
60
+ self .__readPluginList (pluginList , True )
61
+ return True
62
+ file .seek (0 , os .SEEK_SET )
63
+ for line in file :
64
+ line = line .strip ()
65
+ if line [0 ] == u"#" or len (line ) == 0 :
66
+ continue
67
+ if not line .upper () in map (unicode .upper , plugins ):
68
+ plugins .append (line )
69
+ pluginList .setLoadOrder (plugins )
70
+ except IOError :
71
+ self .__readPluginList (pluginList , True )
72
+
73
+ return True
74
+
75
+ def __readPluginList (self , pluginList , useLoadOrder ):
76
+ #QMessageBox.information(None, "__readPluginList", "__readPluginList")
77
+ primary = self .__organizer .managedGame ().primaryPlugins ()
78
+ for pluginName in primary :
79
+ if pluginList .state (pluginName ) != 0 :
80
+ pluginList .setState (pluginName , 2 )
81
+
82
+ plugins = pluginList .pluginNames ()
83
+ # note: list might not be necessary as even though QStringLists are shared, PyQt5 doesn't do that
84
+ pluginsClone = list (plugins )
85
+ for plugin in pluginsClone :
86
+ if plugin .upper () in map (str .upper , primary ):
87
+ plugins [:] = (value for value in plugins if value .upper () != plugin .upper ())
88
+
89
+ def pluginToQDateTime (plugin ):
90
+ lhm = self .__organizer .getMod (pluginList .origin (plugin ))
91
+ lhd = self .__organizer .managedGame ().dataDirectory ()
92
+ if lhm != None :
93
+ lhd = QDir (lhm .absolutePath ())
94
+ lhp = lhd .absoluteFilePath (plugin )
95
+ return QFileInfo (lhp ).lastModified ()
96
+
97
+ plugins .sort (key = pluginToQDateTime )
98
+
99
+ pluginsTxtExists = True
100
+ filePath = os .path .join (self .__organizer .profile ().absolutePath (), "plugins.txt" )
101
+ try :
102
+ with open (filePath , 'r' ) as file :
103
+ file .seek (0 , os .SEEK_END )
104
+ if file .tell () == 0 :
105
+ pluginsTxtExists = False
106
+ file .seek (0 , os .SEEK_SET )
107
+
108
+ activePlugins = []
109
+ inactivePlugins = []
110
+ if pluginsTxtExists :
111
+ for line in file :
112
+ line = line .strip ()
113
+ if len (line ) == 0 or line [0 ] == "#" :
114
+ continue
115
+ pluginList .setState (line , 2 )
116
+ activePlugins .append (line )
117
+
118
+ for pluginName in plugins :
119
+ if pluginName not in activePlugins :
120
+ inactivePlugins .append (pluginName )
121
+
122
+ for pluginName in inactivePlugins :
123
+ pluginList .setState (pluginName , 1 )
124
+ else :
125
+ for pluginName in plugins :
126
+ pluginList .setState (pluginName , 1 )
127
+ except IOError :
128
+ pluginsTxtExists - False
129
+
130
+ if useLoadOrder :
131
+ pluginList .setLoadOrder (primary + plugins )
132
+
133
+ return True
134
+
135
+ class AGame (mobase .IPluginGame ):
136
+
137
+ def __init__ (self ):
138
+ #QMessageBox.information(None, "__init__", "__init__")
139
+ super (AGame , self ).__init__ ()
140
+ self .__featureMap = {}
141
+
142
+ def init (self , organizer ):
143
+ #QMessageBox.information(None, "init", "init")
144
+ self .__featureMap [mobase .GamePlugins ] = AGameGamePlugins (organizer )
145
+ return True
146
+
147
+ def name (self ):
148
+ #QMessageBox.information(None, "name", "name")
149
+ return "Fake Game Support Plugin"
150
+
151
+ def author (self ):
152
+ QMessageBox .information (None , "author" , "author" )
153
+ return "AnyOldName3"
154
+
155
+ def description (self ):
156
+ QMessageBox .information (None , "description" , "description" )
157
+ return self .__tr ("Adds support for a fake game from within Python to see if it is even possible." )
158
+
159
+ def version (self ):
160
+ QMessageBox .information (None , "version" , "version" )
161
+ return mobase .VersionInfo (0 , 1 , 0 , mobase .ReleaseType .prealpha )
162
+
163
+ def isActive (self ):
164
+ QMessageBox .information (None , "isActive" , "isActive" )
165
+ return True
166
+
167
+ def settings (self ):
168
+ #QMessageBox.information(None, "settings", "settings")
169
+ return []
170
+
171
+ def gameName (self ):
172
+ #QMessageBox.information(None, "gameName", "gameName")
173
+ return "A Fake Game"
174
+
175
+ def executables (self ):
176
+ #QMessageBox.information(None, "executables", "executables")
177
+ return [mobase .ExecutableInfo ("A Fake Game" , QFileInfo ("C:/Games/Fake Game/fakegame.exe" ))]
178
+
179
+ def initializeProfile (self , path , settings ):
180
+ #QMessageBox.information(None, "Initialising Profile", "Initialising profile in " + path.path())
181
+ pass
182
+
183
+ def savegameExtension (self ):
184
+ #QMessageBox.information(None, "savegameExtension", "savegameExtension")
185
+ return "sav"
186
+
187
+ def savegameSEExtension (self ):
188
+ QMessageBox .information (None , "savegameSEExtension" , "savegameSEExtension" )
189
+ return "sesav"
190
+
191
+ def steamAPPId (self ):
192
+ #QMessageBox.information(None, "steamAPPId", "steamAPPId")
193
+ return "" # we're not on Steam yet :'(
194
+
195
+ def primaryPlugins (self ):
196
+ #QMessageBox.information(None, "primaryPlugins", "primaryPlugins")
197
+ return ["afakegame.master" , "update.plugin" ]
198
+
199
+ def gameVariants (self ):
200
+ QMessageBox .information (None , "gameVariants" , "gameVariants" )
201
+ return ["Regular" , "Enhanced" ]
202
+
203
+ def gameShortName (self ):
204
+ #QMessageBox.information(None, "gameShortName", "gameShortName")
205
+ return "AFakeGame"
206
+
207
+ def validShortNames (self ):
208
+ return [self .gameShortName (), "Fakier2TheFakerFake" ]
209
+
210
+ def gameNexusName (self ):
211
+ QMessageBox .information (None , "gameNexusName" , "gameNexusName" )
212
+ return "AFakeGame"
213
+
214
+ def iniFiles (self ):
215
+ #QMessageBox.information(None, "iniFiles", "iniFiles")
216
+ return ["fakegame.cfg" , "user.cfg" ]
217
+
218
+ def DLCPlugins (self ):
219
+ QMessageBox .information (None , "DLCPlugins" , "DLCPlugins" )
220
+ return []
221
+
222
+ def CCPlugins (self ):
223
+ QMessageBox .information (None , "CCPlugins" , "CCPlugins" )
224
+ return []
225
+
226
+ def loadOrderMechanism (self ):
227
+ #QMessageBox.information(None, "loadOrderMechanism", "loadOrderMechanism")
228
+ return mobase .LoadOrderMechanism .PluginsTxt
229
+
230
+ def sortMechanism (self ):
231
+ #QMessageBox.information(None, "sortMechanism", "sortMechanism")
232
+ return mobase .SortMechanism .NONE
233
+
234
+ def nexusModOrganizerID (self ):
235
+ QMessageBox .information (None , "nexusModOrganizerID" , "nexusModOrganizerID" )
236
+ return 0
237
+
238
+ def nexusGameID (self ):
239
+ QMessageBox .information (None , "nexusGameID" , "nexusGameID" )
240
+ return 9999
241
+
242
+ def isInstalled (self ):
243
+ #QMessageBox.information(None, "isInstalled", "isInstalled")
244
+ return True
245
+
246
+ def gameIcon (self ):
247
+ #QMessageBox.information(None, "gameIcon", "gameIcon")
248
+ return QIcon ("C:/Games/Fake Game/fakegame.ico" )
249
+
250
+ def gameDirectory (self ):
251
+ #QMessageBox.information(None, "gameDirectory", "gameDirectory")
252
+ return QDir ("C:/Games/Fake Game" )
253
+
254
+ def dataDirectory (self ):
255
+ #QMessageBox.information(None, "dataDirectory", "dataDirectory")
256
+ return QDir ("C:/Games/Fake Game/data" )
257
+
258
+ def setGamePath (self , pathStr ):
259
+ #QMessageBox.information(None, "Changing game path", "Changing game path to " + pathStr)
260
+ pass
261
+
262
+ def documentsDirectory (self ):
263
+ #QMessageBox.information(None, "documentsDirectory", "documentsDirectory")
264
+ return self .gameDirectory ()
265
+
266
+ def savesDirectory (self ):
267
+ QMessageBox .information (None , "savesDirectory" , "savesDirectory" )
268
+ return self .documentsDirectory ()
269
+
270
+ def setGameVariant (self , variantStr ):
271
+ #QMessageBox.information(None, "Setting variant", "Setting variant to " + variantStr)
272
+ pass
273
+
274
+ def binaryName (self ):
275
+ QMessageBox .information (None , "binaryName" , "binaryName" )
276
+ return "fakegame.exe"
277
+
278
+ def looksValid (self , aQDir ):
279
+ #QMessageBox.information(None, "looksValid", "looksValid")
280
+ return True
281
+
282
+ def gameVersion (self ):
283
+ QMessageBox .information (None , "gameVersion" , "gameVersion" )
284
+ return "1"
285
+
286
+ def getLauncherName (self ):
287
+ QMessageBox .information (None , "getLauncherName" , "getLauncherName" )
288
+ return "fakegamelauncher.exe"
289
+
290
+ def _featureList (self ):
291
+ return self .__featureMap
292
+
293
+ def __tr (self , str ):
294
+ return QCoreApplication .translate ("AGame" , str )
295
+
296
+ def createPlugin ():
297
+ return AGame ()
0 commit comments