@@ -78,6 +78,7 @@ var install = function(releasePath, opt_destPath, opt_options) {
78
78
} ) ;
79
79
var runtimeInfo ;
80
80
var zipRootPath ;
81
+ var zipPackagePath ;
81
82
82
83
var packageLocations = gameInfo . getPackageLocations ( ) ;
83
84
var checkPackageLocations = function ( entry ) {
@@ -106,18 +107,50 @@ var install = function(releasePath, opt_destPath, opt_options) {
106
107
if ( ! packageEntry ) {
107
108
return reject ( "no package.json found in " + releasePath ) ;
108
109
}
109
- zipRootPath = packageEntry . name . replace ( / \\ / g, "/" ) ;
110
- zipRootPath = zipRootPath . substring ( 0 , zipRootPath . indexOf ( "/" ) ) ;
110
+ zipPackagePath = packageEntry . name . replace ( / \\ / g, "/" ) ;
111
+ zipRootPath = zipPackagePath . substring ( 0 , zipPackagePath . indexOf ( "/" ) ) ;
111
112
runtimeInfo = gameInfo . parseGameInfo ( packageEntry . asText ( ) , packageEntry . name , zipRootPath ) ;
112
113
} catch ( e ) {
113
114
return reject ( "could not parse package.json. Maybe this is not a HappyFunTimes game?" ) ;
114
115
}
115
116
117
+ // Check it's got the required files
118
+ try {
119
+ var zipPackageDir = path . dirname ( zipPackagePath ) ;
120
+ var fileNames = entries . map ( function ( entry ) {
121
+ return path . relative ( zipPackageDir , entry . name . replace ( / [ \\ / ] / g, path . sep ) ) . replace ( / \\ / g, "/" ) ;
122
+ } ) ;
123
+ gameInfo . checkRequiredFiles ( runtimeInfo , fileNames ) ;
124
+ } catch ( e ) {
125
+ return reject ( e ) ;
126
+ }
127
+
116
128
var info = runtimeInfo . info ;
117
129
var hftInfo = info . happyFunTimes ;
118
130
var gameId = runtimeInfo . originalGameId ;
131
+ var safeGameId = releaseUtils . safeishName ( gameId ) ;
119
132
var destBasePath ;
120
133
134
+ var fileExists = { } ;
135
+ entries . forEach ( function ( entry ) {
136
+ var filename = entry . name . replace ( / \\ / g, "/" ) . replace ( / .* ?\/ / , "" ) ;
137
+ fileExists [ filename ] = true ;
138
+ } ) ;
139
+
140
+ // Check for more files that should exist.
141
+ // Games that are "added" don't need this but games
142
+ // that are "installed" do.
143
+ log ( "checking gametype: " + hftInfo . gameType ) ;
144
+ if ( hftInfo . gameType . toLowerCase ( ) === "unity3d" ) {
145
+ var exePath = platformInfo . exePath ;
146
+ if ( exePath ) {
147
+ exePath = strings . replaceParams ( exePath , { gameId : safeGameId } ) ;
148
+ if ( ! fileExists [ exePath ] ) {
149
+ return reject ( "path not found: " + exePath + "\nIs this the correct zip file for " + platformInfo . id + "?" ) ;
150
+ }
151
+ }
152
+ }
153
+
121
154
// is it already installed?
122
155
var installedGame = gameDB . getGameById ( gameId ) ;
123
156
if ( installedGame ) {
@@ -130,55 +163,66 @@ var install = function(releasePath, opt_destPath, opt_options) {
130
163
}
131
164
}
132
165
133
- var safeGameId = releaseUtils . safeishName ( gameId ) ;
134
-
135
166
if ( ! destBasePath ) {
136
167
// make the dir after we're sure we're ready to install
137
168
destBasePath = path . join ( config . getConfig ( ) . gamesDir , safeGameId ) ;
138
169
}
139
170
140
171
destBasePath = opt_destPath ? opt_destPath : destBasePath ;
141
172
173
+ // Check for bad paths
174
+ var bad = false ;
175
+ var errors = [ ] ;
176
+ entries . forEach ( function ( entry ) {
177
+ if ( bad ) {
178
+ return ;
179
+ }
180
+ var filePath = entry . name . substring ( zipRootPath . length + 1 ) ;
181
+ var destPath = path . resolve ( path . join ( destBasePath , filePath ) ) ;
182
+ if ( destPath . substring ( 0 , destBasePath . length ) !== destBasePath ) {
183
+ errors . push ( "ERROR: bad zip file. Path would write outside game folder" ) ;
184
+ bad = true ;
185
+ }
186
+ } ) ;
187
+
188
+ if ( bad ) {
189
+ // Should delete all work here?
190
+ return reject ( errors . join ( "\n" ) ) ;
191
+ }
192
+
142
193
console . log ( "installing to: " + destBasePath ) ;
143
194
if ( ! options . dryRun ) {
144
195
mkdirp . sync ( destBasePath ) ;
145
196
}
146
197
147
198
var files = [ ] ;
148
- var errors = [ ] ;
149
- var bad = false ;
150
199
entries . forEach ( function ( entry ) {
151
200
if ( bad ) {
152
201
return ;
153
202
}
154
203
var filePath = entry . name . substring ( zipRootPath . length + 1 ) ;
155
204
files . push ( filePath ) ;
156
205
var destPath = path . resolve ( path . join ( destBasePath , filePath ) ) ;
157
- if ( destPath . substring ( 0 , destBasePath . length ) !== destBasePath ) {
158
- errors . push ( "ERROR: bad zip file. Path would write outside game folder" ) ;
159
- bad = true ;
160
- } else {
161
- var isDir = entry . dir ;
162
- if ( destPath . substr ( - 1 ) === "/" || destPath . substr ( - 1 ) === "\\" ) {
163
- destPath = destPath . substr ( 0 , destPath . length - 1 ) ;
164
- isDir = true ;
206
+ var isDir = entry . dir ;
207
+ if ( destPath . substr ( - 1 ) === "/" || destPath . substr ( - 1 ) === "\\" ) {
208
+ destPath = destPath . substr ( 0 , destPath . length - 1 ) ;
209
+ isDir = true ;
210
+ }
211
+ //??
212
+ if ( isDir ) {
213
+ log ( "mkdir : " + destPath ) ;
214
+ if ( ! options . dryRun ) {
215
+ mkdirp . sync ( destPath ) ;
165
216
}
166
- //??
167
- if ( isDir ) {
168
- log ( "mkdir : " + destPath ) ;
169
- if ( ! options . dryRun ) {
170
- mkdirp . sync ( destPath ) ;
171
- }
172
- } else {
173
- log ( "install: " + entry . name + " -> " + destPath ) ;
174
- if ( ! options . dryRun ) {
175
- var dirPath = path . dirname ( destPath ) ;
176
- if ( ! fs . existsSync ( dirPath ) ) {
177
- log ( "mkdir : " + dirPath ) ;
178
- mkdirp . sync ( dirPath ) ;
179
- }
180
- fs . writeFileSync ( destPath , entry . asNodeBuffer ( ) ) ;
217
+ } else {
218
+ log ( "install: " + entry . name + " -> " + destPath ) ;
219
+ if ( ! options . dryRun ) {
220
+ var dirPath = path . dirname ( destPath ) ;
221
+ if ( ! fs . existsSync ( dirPath ) ) {
222
+ log ( "mkdir : " + dirPath ) ;
223
+ mkdirp . sync ( dirPath ) ;
181
224
}
225
+ fs . writeFileSync ( destPath , entry . asNodeBuffer ( ) ) ;
182
226
}
183
227
}
184
228
} ) ;
@@ -188,8 +232,7 @@ var install = function(releasePath, opt_destPath, opt_options) {
188
232
return reject ( errors . join ( "\n" ) ) ;
189
233
}
190
234
191
- // Should this be in the zip?
192
- log ( "checking gametype: " + hftInfo . gameType ) ;
235
+ // Set the executable bit
193
236
if ( hftInfo . gameType . toLowerCase ( ) === "unity3d" ) {
194
237
var exePath = platformInfo . exePath ;
195
238
if ( exePath ) {
0 commit comments