├── README.md ├── YoukuAntiADs@harv.c.uc.js ├── YoukuAntiADs@harv.c_57+.uc.js └── swf ├── iqiyi5.swf ├── iqiyi_out.swf ├── ku6.swf ├── ku6_out.swf ├── letvsdk.swf ├── loader.swf ├── player.swf ├── pptv.swf ├── sohu_live.swf └── tudou.swf /README.md: -------------------------------------------------------------------------------- 1 | FireLoaclSWF 2 | ============ 3 | 2017.11.26 4 | 5 | +新增57可用版本,[UC使用方法](https://github.com/Endor8/userChrome.js/tree/master/userChrome)。 6 | 7 | youku tudou在57+上已默认启用HTML5,因此已默认禁用相关规则,请用abp/ubo/YAPfY过滤广告。 8 | 9 | iqiyi建议在TM上使用[GM](https://greasyfork.org/scripts/28356)来屏蔽广告。 10 | 11 | pptv播放器过老造成无法播放且可用abp/ubo过滤,因此不再支持此网站。 12 | 13 | 14 | 2016.11.19 15 | 16 | 优酷播放器底部问题可以临时用css修正下 17 | 18 | @-moz-document domain("v.youku.com"){ 19 | .danmuoff .vpactionv5_iframe_wrap {top: auto !important;} 20 | .play_area{margin-bottom: 70px !important;} 21 | } 22 | 23 | 我修改过的UC版本地视频网站播放器(Firefox专用)打包版,请解压swf.rar到Profiles\chrome\后食用。 24 | 25 | 支持的网站:youku tudou iqiyi letv sohu。 26 | 27 | UC脚本修改自15536900和cinhoo,SWF播放器大部分采用15536900@kafan的,iqiyi_out/Letv_live播放器采用catcat520@kafan的。 28 | 29 | 修改原理见我原帖:https://g.mozest.com/viewthread.php?tid=43130&page=2#pid300698 30 | 31 | 感谢 cinhoo,15536900,catcat520 32 | 33 | Git@OSC地址:https://git.oschina.net/jnzk/FireLocalSWF -------------------------------------------------------------------------------- /YoukuAntiADs@harv.c.uc.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name youkuantiads.uc.js 3 | // @namespace YoukuAntiADs@harv.c 4 | // @description 视频网站去黑屏 5 | // @include chrome://browser/content/browser.xul 6 | // @author harv.c & 15536900 7 | // @homepage https://github.com/kafan15536900/ 8 | // @version 2.0.0.5 9 | // @updateURL 10 | // ==/UserScript== 11 | (function() { 12 | // YoukuAntiADs, request observer 13 | function YoukuAntiADs() {}; 14 | var swfNode = Services.dirsvc.get('UChrm', Ci.nsILocalFile); swfNode.appendRelativePath("swf"); 15 | YoukuAntiADs.prototype = { 16 | SITES: { 17 | /* 'youku_loader': { 18 | 'target': 'loader.swf', 19 | 'find': /http:\/\/static\.youku\.com(\/v[\d\.]*)?\/v\/.*\/loaders?\.swf/i 20 | }, 21 | 'youku_player': { 22 | 'target': 'player.swf', 23 | 'find': /http:\/\/static\.youku\.com(\/v[\d\.]*)?\/v\/swf\/(.*\/)?q?player.*\.swf/i 24 | }, 25 | 'tudou': { 26 | 'target': 'tudou.swf', 27 | 'find': /http:\/\/static\.youku\.com(\/v[\d\.]*)?\/v\/custom\/.*\/q?player.*\.swf/i 28 | },*/ 29 | 'iqiyi': { 30 | 'target': 'iqiyi5.swf', 31 | 'find': /https?:\/\/www\.iqiyi\.com\/(player\/\d+\/Player|common\/flashplayer\/\d+\/((Main)?Player_.*|[\d]{4}[a-z]+((?!aa|dc32).){6,7}))\.swf/i 32 | }, 33 | 'iqiy_out': { 34 | 'target': 'iqiyi_out.swf', 35 | 'find': /https?:\/\/www\.iqiyi\.com\/common\/flashplayer\/\d+\/SharePlayer_.*\.swf/i 36 | }, 37 | 'letvsdk': { 38 | 'target': 'letvsdk.swf', 39 | 'find': /http:\/\/player\.letvcdn\.com\/.*\/newplayer\/LetvPlayerSDK\.swf/i 40 | }, 41 | 'sohu_live': { 42 | 'target': 'sohu_live.swf', 43 | 'find': /https?:\/\/(tv\.sohu\.com\/upload\/swf\/(p2p\/)?\d+|(\d+\.){3}\d+\/wp8player)\/Main\.swf/i 44 | }, 45 | /* 'pptv': { 46 | 'target': 'pptv.swf', 47 | 'find': /http:\/\/player\.pplive\.cn\/ikan\/.*\/player4player2\.swf/i 48 | },*/ 49 | /* 'example3': { 50 | 'method':'INLINE', 51 | 're': [ 52 | 'playArea .player{height:auto}', 53 | '.vpactionv5_iframe_wrap{top:auto$1}.' 54 | ], 55 | 'match':[ 56 | /\.playArea \.player{height:\d+px}/i, 57 | / \.vpactionv5_iframe_wrap{top:\d+px(.*)}\./i 58 | ], 59 | 'find': /http:\/\/donotexist.com\/test.css/i 60 | }*/ 61 | }, 62 | REFRULES: { 63 | 'tucao': { 64 | 'target': 'http://www.tudou.com/', 65 | 'find': /vr\.tudou\.com/i 66 | } 67 | }, 68 | REDIRRULES: { 69 | /* 'redirexample1': { 70 | 'target': 'http://anothersite.com/player.swf', 71 | 'find': /http:\/\/donotexist.com\/test.swf/i 72 | }*/ 73 | }, 74 | os: Cc['@mozilla.org/observer-service;1'] 75 | .getService(Ci.nsIObserverService), 76 | ios: Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService), 77 | init: function() { 78 | return; 79 | }, 80 | // getContent, get modified stream 81 | getContent: function(site, callback) { 82 | console.log(site['target']); 83 | //ADD using nsILocalFile API to remove warning from NetUtil.asyncFetch 84 | var pSource = site['target']; 85 | try{ 86 | if(!/(profiles|https?:)/i.test(pSource)) //skip when match local_file(in profiles dir) or HTTP(S) uri 87 | { 88 | pSource = swfNode.clone(); 89 | pSource.appendRelativePath(site['target']); 90 | } 91 | }catch(e) {} 92 | // 93 | NetUtil.asyncFetch(pSource, function(inputStream, status) { 94 | var binaryOutputStream = Cc['@mozilla.org/binaryoutputstream;1'] 95 | .createInstance(Ci['nsIBinaryOutputStream']); 96 | var storageStream = Cc['@mozilla.org/storagestream;1'] 97 | .createInstance(Ci['nsIStorageStream']); 98 | if (!Components.isSuccessCode(status)) { 99 | // Handle error 100 | console.log('Fetch Failed'); 101 | } 102 | else 103 | { 104 | var count = inputStream.available(); 105 | var data = NetUtil.readInputStreamToString(inputStream, count); 106 | 107 | storageStream.init(512, count, null); 108 | binaryOutputStream.setOutputStream(storageStream.getOutputStream(0)); 109 | binaryOutputStream.writeBytes(data, count); 110 | 111 | site['storageStream'] = storageStream; 112 | site['count'] = count; 113 | } 114 | if(typeof callback === 'function') { 115 | callback(); 116 | } 117 | }); 118 | }, 119 | getWindowForRequest: function(request){ 120 | if(request instanceof Ci.nsIRequest){ 121 | try{ 122 | if(request.notificationCallbacks){ 123 | return request.notificationCallbacks 124 | .getInterface(Ci.nsILoadContext) 125 | .associatedWindow; 126 | } 127 | } catch(e) {} 128 | try{ 129 | if(request.loadGroup && request.loadGroup.notificationCallbacks){ 130 | return request.loadGroup.notificationCallbacks 131 | .getInterface(Ci.nsILoadContext) 132 | .associatedWindow; 133 | } 134 | } catch(e) {} 135 | } 136 | return null; 137 | }, 138 | observe: function(aSubject, aTopic, aData) { 139 | //Observer Funtions 140 | if (aTopic == "http-on-modify-request") { 141 | //Headers Modifier 142 | var httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel); 143 | for(var i in this.REFRULES) { 144 | var rule = this.REFRULES[i]; 145 | try { 146 | var URI = httpChannel.originalURI.spec; 147 | if(rule['find'].test(URI)) { 148 | console.log("Headers Modifier"); 149 | //console.log(URI); 150 | if(rule['target'] != "") 151 | { 152 | httpChannel.referrer = this.ios.newURI(rule['target'], null, null); 153 | } 154 | httpChannel.setRequestHeader('Referer', rule['target'], false); 155 | break; 156 | } 157 | } 158 | catch(e) { 159 | alert(e); 160 | break; 161 | } 162 | } 163 | //URL Redirector 164 | for(var i in this.REDIRRULES) { 165 | var rule = this.REDIRRULES[i]; 166 | try { 167 | var oriURI = httpChannel.originalURI.spec; 168 | var URI = httpChannel.URI.spec; 169 | if(rule['find'].test(oriURI) && rule['find'].test(URI)) { //prevent from loop 170 | console.log("URL Redirector"); 171 | console.log(URI); 172 | if(rule['target'] != "") 173 | { 174 | httpChannel.redirectTo(this.ios.newURI(oriURI.replace(rule['find'],rule['target']), null, null)); 175 | } 176 | break; 177 | } 178 | } 179 | catch(e) { 180 | alert(e); 181 | break; 182 | } 183 | } 184 | return; 185 | } 186 | //Content Replacer 187 | if(aTopic != 'http-on-examine-response') return; 188 | 189 | var http = aSubject.QueryInterface(Ci.nsIHttpChannel); 190 | for(var i in this.SITES) { 191 | var site = this.SITES[i]; 192 | if(site['find'].test(http.URI.spec)) { 193 | if(!site['storageStream'] || !site['count']) { 194 | http.suspend(); 195 | console.log("Content Replacer"); 196 | switch(site['method']) 197 | { 198 | case 'INLINE': 199 | http.resume(); 200 | break; 201 | 202 | case 'BLOCK': 203 | console.log("Blocking.."); 204 | aSubject.cancel(Cr.NS_BINDING_ABORTED); //aSubject.cancel(Components.results.NS_BINDING_ABORTED); 205 | http.resume(); 206 | break 207 | break; 208 | 209 | default: 210 | this.getContent(site, function() { 211 | console.log("Getting Files.."); 212 | http.resume(); 213 | }); 214 | break; 215 | } 216 | } 217 | //TrackingListener Chain 218 | var newListener = new TrackingListener(); 219 | aSubject.QueryInterface(Ci.nsITraceableChannel); 220 | newListener.originalListener = aSubject.setNewListener(newListener); 221 | newListener.site = site; 222 | newListener.aSubject = aSubject; 223 | break; 224 | } 225 | } 226 | }, 227 | QueryInterface: function(aIID) { 228 | if(aIID.equals(Ci.nsISupports) || aIID.equals(Ci.nsIObserver)) 229 | { 230 | return this; 231 | } 232 | else 233 | { 234 | return Cr.NS_ERROR_NO_INTERFACE; 235 | } 236 | }, 237 | register: function() { 238 | this.init(); 239 | this.os.addObserver(this, 'http-on-examine-response', false); 240 | this.os.addObserver(this, 'http-on-modify-request', false); 241 | }, 242 | unregister: function() { 243 | this.os.removeObserver(this, 'http-on-examine-response', false); 244 | this.os.removeObserver(this, 'http-on-modify-request', false); 245 | } 246 | }; 247 | 248 | function CCIN(cName, ifaceName) { 249 | return Cc[cName].createInstance(Ci[ifaceName]); 250 | } 251 | 252 | // TrackingListener, redirect original content to modified one 253 | function TrackingListener() { 254 | //Init state 255 | this.originalListener = null; 256 | this.site = null; 257 | this.aSubject = null; 258 | this.originalData = null; 259 | } 260 | TrackingListener.prototype = { 261 | onStartRequest: function(request, context) { 262 | //console.log('onStartRequest'); 263 | this.originalListener.onStartRequest(request, context); 264 | }, 265 | onStopRequest: function(request, context) { 266 | //console.log('onStopRequest'); 267 | this.originalListener.onStopRequest(request, context, Cr.NS_OK); 268 | }, 269 | onDataAvailable: function(request, context, inputStream, offset, count) { 270 | //Modify Content in-flight 271 | //Inline Modifier 272 | //When respone code is not 200,Flash won't accept the content...nothing i can do to bypass it except to rewrite firefox's src 273 | 274 | var chttp = this.aSubject.QueryInterface(Ci.nsIHttpChannel); 275 | console.log(chttp.URI.spec); 276 | var csite = null; 277 | for(var i in YoukuAntiADs.prototype.SITES) 278 | { 279 | var site = YoukuAntiADs.prototype.SITES[i]; 280 | if(site['find'].test(chttp.URI.spec)) 281 | { 282 | //When offset is not equal 0, it means this request is partial-load. 283 | //The site['storageStream'] and site['count'] may have already defined at sometimes before. 284 | //So here we have to ignore the existance of site['storageStream'] or site['count'] 285 | //just replace the content, calcuate count, pass the correct value to the original chian. 286 | switch(site['method']) 287 | { 288 | case 'INLINE': 289 | console.log("Inline Modifier"); 290 | console.log(chttp.URI.spec); 291 | if (site['match'].length == site['re'].length) 292 | { 293 | chttp.suspend(); 294 | console.log("Working.."); 295 | var binaryOutputStream = Cc['@mozilla.org/binaryoutputstream;1'] 296 | .createInstance(Ci['nsIBinaryOutputStream']); 297 | var storageStream = Cc['@mozilla.org/storagestream;1'] 298 | .createInstance(Ci['nsIStorageStream']); 299 | 300 | var count = inputStream.available(); 301 | var data = NetUtil.readInputStreamToString(inputStream, count); 302 | 303 | 304 | console.log("beforelength:"+count); 305 | //console.log("beforedata:"+data); 306 | 307 | for(var u in site['match']) { 308 | var match = site['match'][u]; 309 | var re = site['re'][u]; 310 | data = data.replace(match,re); 311 | 312 | } 313 | count = data.length; 314 | //== 315 | console.log("afterlength:"+count); 316 | //console.log("afterdata:"+ data); 317 | 318 | storageStream.init(512, count, null); 319 | binaryOutputStream.setOutputStream(storageStream.getOutputStream(0)); 320 | binaryOutputStream.writeBytes(data, count); 321 | 322 | site['storageStream'] = storageStream; 323 | site['count'] = count; 324 | 325 | csite = site; 326 | chttp.resume(); 327 | console.log("Complete.."); 328 | } 329 | else 330 | { 331 | console.log("Error..");; 332 | } 333 | break; 334 | 335 | default: 336 | break; 337 | } 338 | break; 339 | } 340 | } 341 | //Replace the Original-Stream to the Changed-Stream 342 | if(csite) 343 | { 344 | //fix a historical bug when dealing with a request which offset > 0 345 | this.originalListener.onDataAvailable(request, context, csite['storageStream'].newInputStream(0), offset, csite['count']); 346 | } 347 | else 348 | { 349 | if(this.site['storageStream'] || this.site['count']) 350 | { 351 | //When partial-load and if the count and offset is not equal to the original one 352 | //'http channel Listener OnDataAvailable contract violation' warning will be fired, but that's all right nsHttpChannel will fix it. 353 | this.originalListener.onDataAvailable(request, context, this.site['storageStream'].newInputStream(0), 0, this.site['count']); 354 | } 355 | else 356 | { 357 | //Ignore 358 | this.originalListener.onDataAvailable(request, context, inputStream, offset, count); 359 | } 360 | } 361 | } 362 | }; 363 | 364 | // register observer 365 | var y = new YoukuAntiADs(); 366 | if(location == 'chrome://browser/content/browser.xul') { 367 | y.register(); 368 | } 369 | 370 | // unregister observer 371 | window.addEventListener('unload', function() { 372 | if(location == 'chrome://browser/content/browser.xul') { 373 | y.unregister(); 374 | } 375 | }); 376 | })(); -------------------------------------------------------------------------------- /YoukuAntiADs@harv.c_57+.uc.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name youkuantiads.uc.js 3 | // @namespace YoukuAntiADs@harv.c 4 | // @description 视频网站去黑屏 5 | // @include chrome://browser/content/browser.xul 6 | // @author harv.c & 15536900 7 | // @homepage https://github.com/kafan15536900/ 8 | // @version 2.0.0.5 9 | // @updateURL 10 | // ==/UserScript== 11 | (function() { 12 | // YoukuAntiADs, request observer 13 | function YoukuAntiADs() {}; 14 | var swfNode = Services.dirsvc.get('UChrm', Ci.nsIFile); swfNode.appendRelativePath("swf"); 15 | YoukuAntiADs.prototype = { 16 | SITES: { 17 | /* 'youku_loader': { 18 | 'target': 'loader.swf', 19 | 'find': /http:\/\/static\.youku\.com(\/v[\d\.]*)?\/v\/.*\/loaders?\.swf/i 20 | }, 21 | 'youku_player': { 22 | 'target': 'player.swf', 23 | 'find': /http:\/\/static\.youku\.com(\/v[\d\.]*)?\/v\/swf\/(.*\/)?q?player.*\.swf/i 24 | }, 25 | 'tudou': { 26 | 'target': 'tudou.swf', 27 | 'find': /http:\/\/static\.youku\.com(\/v[\d\.]*)?\/v\/custom\/.*\/q?player.*\.swf/i 28 | }, 29 | */ 30 | 'iqiyi': { 31 | 'target': 'iqiyi5.swf', 32 | 'find': /https?:\/\/www\.iqiyi\.com\/(player\/\d+\/Player|common\/flashplayer\/\d+\/((Main)?Player_.*|[\d]{4}[a-z]+((?!aa|dc32).){6,7}))\.swf/i 33 | }, 34 | 'iqiy_out': { 35 | 'target': 'iqiyi_out.swf', 36 | 'find': /https?:\/\/www\.iqiyi\.com\/common\/flashplayer\/\d+\/SharePlayer_.*\.swf/i 37 | }, 38 | 'letvsdk': { 39 | 'target': 'letvsdk.swf', 40 | 'find': /http:\/\/player\.letvcdn\.com\/.*\/newplayer\/LetvPlayerSDK\.swf/i 41 | }, 42 | 'sohu_live': { 43 | 'target': 'sohu_live.swf', 44 | 'find': /https?:\/\/(tv\.sohu\.com\/upload\/swf\/(p2p\/)?\d+|(\d+\.){3}\d+\/wp8player)\/Main\.swf/i 45 | }, 46 | /* 'pptv': { 47 | 'target': 'pptv.swf', 48 | 'find': /http:\/\/player\.pplive\.cn\/ikan\/.*\/player4player2\.swf/i 49 | } 50 | /* 'example3': { 51 | 'method':'INLINE', 52 | 're': [ 53 | 'playArea .player{height:auto}', 54 | '.vpactionv5_iframe_wrap{top:auto$1}.' 55 | ], 56 | 'match':[ 57 | /\.playArea \.player{height:\d+px}/i, 58 | / \.vpactionv5_iframe_wrap{top:\d+px(.*)}\./i 59 | ], 60 | 'find': /http:\/\/donotexist.com\/test.css/i 61 | }*/ 62 | }, 63 | REFRULES: { 64 | 'tucao': { 65 | 'target': 'http://www.tudou.com/', 66 | 'find': /vr\.tudou\.com/i 67 | } 68 | }, 69 | REDIRRULES: { 70 | /* 'redirexample1': { 71 | 'target': 'http://anothersite.com/player.swf', 72 | 'find': /http:\/\/donotexist.com\/test.swf/i 73 | }*/ 74 | }, 75 | os: Cc['@mozilla.org/observer-service;1'] 76 | .getService(Ci.nsIObserverService), 77 | ios: Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService), 78 | init: function() { 79 | return; 80 | }, 81 | // getContent, get modified stream 82 | getContent: function(site, callback) { 83 | console.log(site['target']); 84 | //ADD using nsILocalFile API to remove warning from NetUtil.asyncFetch 85 | var pSource = site['target']; 86 | try{ 87 | if(!/(profiles|https?:)/i.test(pSource)) //skip when match local_file(in profiles dir) or HTTP(S) uri 88 | { 89 | pSource = swfNode.clone(); 90 | pSource.appendRelativePath(site['target']); 91 | } 92 | }catch(e) {} 93 | // 94 | NetUtil.asyncFetch(pSource, function(inputStream, status) { 95 | var binaryOutputStream = Cc['@mozilla.org/binaryoutputstream;1'] 96 | .createInstance(Ci['nsIBinaryOutputStream']); 97 | var storageStream = Cc['@mozilla.org/storagestream;1'] 98 | .createInstance(Ci['nsIStorageStream']); 99 | if (!Components.isSuccessCode(status)) { 100 | // Handle error 101 | console.log('Fetch Failed'); 102 | } 103 | else 104 | { 105 | var count = inputStream.available(); 106 | var data = NetUtil.readInputStreamToString(inputStream, count); 107 | 108 | storageStream.init(512, count, null); 109 | binaryOutputStream.setOutputStream(storageStream.getOutputStream(0)); 110 | binaryOutputStream.writeBytes(data, count); 111 | 112 | site['storageStream'] = storageStream; 113 | site['count'] = count; 114 | } 115 | if(typeof callback === 'function') { 116 | callback(); 117 | } 118 | }); 119 | }, 120 | getWindowForRequest: function(request){ 121 | if(request instanceof Ci.nsIRequest){ 122 | try{ 123 | if(request.notificationCallbacks){ 124 | return request.notificationCallbacks 125 | .getInterface(Ci.nsILoadContext) 126 | .associatedWindow; 127 | } 128 | } catch(e) {} 129 | try{ 130 | if(request.loadGroup && request.loadGroup.notificationCallbacks){ 131 | return request.loadGroup.notificationCallbacks 132 | .getInterface(Ci.nsILoadContext) 133 | .associatedWindow; 134 | } 135 | } catch(e) {} 136 | } 137 | return null; 138 | }, 139 | observe: function(aSubject, aTopic, aData) { 140 | //Observer Funtions 141 | if (aTopic == "http-on-modify-request") { 142 | //Headers Modifier 143 | var httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel); 144 | for(var i in this.REFRULES) { 145 | var rule = this.REFRULES[i]; 146 | try { 147 | var URI = httpChannel.originalURI.spec; 148 | if(rule['find'].test(URI)) { 149 | console.log("Headers Modifier"); 150 | //console.log(URI); 151 | if(rule['target'] != "") 152 | { 153 | httpChannel.referrer = this.ios.newURI(rule['target'], null, null); 154 | } 155 | httpChannel.setRequestHeader('Referer', rule['target'], false); 156 | break; 157 | } 158 | } 159 | catch(e) { 160 | alert(e); 161 | break; 162 | } 163 | } 164 | //URL Redirector 165 | for(var i in this.REDIRRULES) { 166 | var rule = this.REDIRRULES[i]; 167 | try { 168 | var oriURI = httpChannel.originalURI.spec; 169 | var URI = httpChannel.URI.spec; 170 | if(rule['find'].test(oriURI) && rule['find'].test(URI)) { //prevent from loop 171 | console.log("URL Redirector"); 172 | console.log(URI); 173 | if(rule['target'] != "") 174 | { 175 | httpChannel.redirectTo(this.ios.newURI(oriURI.replace(rule['find'],rule['target']), null, null)); 176 | } 177 | break; 178 | } 179 | } 180 | catch(e) { 181 | alert(e); 182 | break; 183 | } 184 | } 185 | return; 186 | } 187 | //Content Replacer 188 | if(aTopic != 'http-on-examine-response') return; 189 | 190 | var http = aSubject.QueryInterface(Ci.nsIHttpChannel); 191 | for(var i in this.SITES) { 192 | var site = this.SITES[i]; 193 | if(site['find'].test(http.URI.spec)) { 194 | if(!site['storageStream'] || !site['count']) { 195 | http.suspend(); 196 | console.log("Content Replacer"); 197 | switch(site['method']) 198 | { 199 | case 'INLINE': 200 | http.resume(); 201 | break; 202 | 203 | case 'BLOCK': 204 | console.log("Blocking.."); 205 | aSubject.cancel(Cr.NS_BINDING_ABORTED); //aSubject.cancel(Components.results.NS_BINDING_ABORTED); 206 | http.resume(); 207 | break 208 | break; 209 | 210 | default: 211 | this.getContent(site, function() { 212 | console.log("Getting Files.."); 213 | http.resume(); 214 | }); 215 | break; 216 | } 217 | } 218 | //TrackingListener Chain 219 | var newListener = new TrackingListener(); 220 | aSubject.QueryInterface(Ci.nsITraceableChannel); 221 | newListener.originalListener = aSubject.setNewListener(newListener); 222 | newListener.site = site; 223 | newListener.aSubject = aSubject; 224 | break; 225 | } 226 | } 227 | }, 228 | QueryInterface: function(aIID) { 229 | if(aIID.equals(Ci.nsISupports) || aIID.equals(Ci.nsIObserver)) 230 | { 231 | return this; 232 | } 233 | else 234 | { 235 | return Cr.NS_ERROR_NO_INTERFACE; 236 | } 237 | }, 238 | register: function() { 239 | this.init(); 240 | this.os.addObserver(this, 'http-on-examine-response', false); 241 | this.os.addObserver(this, 'http-on-modify-request', false); 242 | }, 243 | unregister: function() { 244 | this.os.removeObserver(this, 'http-on-examine-response', false); 245 | this.os.removeObserver(this, 'http-on-modify-request', false); 246 | } 247 | }; 248 | 249 | function CCIN(cName, ifaceName) { 250 | return Cc[cName].createInstance(Ci[ifaceName]); 251 | } 252 | 253 | // TrackingListener, redirect original content to modified one 254 | function TrackingListener() { 255 | //Init state 256 | this.originalListener = null; 257 | this.site = null; 258 | this.aSubject = null; 259 | this.originalData = null; 260 | } 261 | TrackingListener.prototype = { 262 | onStartRequest: function(request, context) { 263 | //console.log('onStartRequest'); 264 | this.originalListener.onStartRequest(request, context); 265 | }, 266 | onStopRequest: function(request, context) { 267 | //console.log('onStopRequest'); 268 | this.originalListener.onStopRequest(request, context, Cr.NS_OK); 269 | }, 270 | onDataAvailable: function(request, context, inputStream, offset, count) { 271 | //Modify Content in-flight 272 | //Inline Modifier 273 | //When respone code is not 200,Flash won't accept the content...nothing i can do to bypass it except to rewrite firefox's src 274 | 275 | var chttp = this.aSubject.QueryInterface(Ci.nsIHttpChannel); 276 | console.log(chttp.URI.spec); 277 | var csite = null; 278 | for(var i in YoukuAntiADs.prototype.SITES) 279 | { 280 | var site = YoukuAntiADs.prototype.SITES[i]; 281 | if(site['find'].test(chttp.URI.spec)) 282 | { 283 | //When offset is not equal 0, it means this request is partial-load. 284 | //The site['storageStream'] and site['count'] may have already defined at sometimes before. 285 | //So here we have to ignore the existance of site['storageStream'] or site['count'] 286 | //just replace the content, calcuate count, pass the correct value to the original chian. 287 | switch(site['method']) 288 | { 289 | case 'INLINE': 290 | console.log("Inline Modifier"); 291 | console.log(chttp.URI.spec); 292 | if (site['match'].length == site['re'].length) 293 | { 294 | chttp.suspend(); 295 | console.log("Working.."); 296 | var binaryOutputStream = Cc['@mozilla.org/binaryoutputstream;1'] 297 | .createInstance(Ci['nsIBinaryOutputStream']); 298 | var storageStream = Cc['@mozilla.org/storagestream;1'] 299 | .createInstance(Ci['nsIStorageStream']); 300 | 301 | var count = inputStream.available(); 302 | var data = NetUtil.readInputStreamToString(inputStream, count); 303 | 304 | 305 | console.log("beforelength:"+count); 306 | //console.log("beforedata:"+data); 307 | 308 | for(var u in site['match']) { 309 | var match = site['match'][u]; 310 | var re = site['re'][u]; 311 | data = data.replace(match,re); 312 | 313 | } 314 | count = data.length; 315 | //== 316 | console.log("afterlength:"+count); 317 | //console.log("afterdata:"+ data); 318 | 319 | storageStream.init(512, count, null); 320 | binaryOutputStream.setOutputStream(storageStream.getOutputStream(0)); 321 | binaryOutputStream.writeBytes(data, count); 322 | 323 | site['storageStream'] = storageStream; 324 | site['count'] = count; 325 | 326 | csite = site; 327 | chttp.resume(); 328 | console.log("Complete.."); 329 | } 330 | else 331 | { 332 | console.log("Error..");; 333 | } 334 | break; 335 | 336 | default: 337 | break; 338 | } 339 | break; 340 | } 341 | } 342 | //Replace the Original-Stream to the Changed-Stream 343 | if(csite) 344 | { 345 | //fix a historical bug when dealing with a request which offset > 0 346 | this.originalListener.onDataAvailable(request, context, csite['storageStream'].newInputStream(0), offset, csite['count']); 347 | } 348 | else 349 | { 350 | if(this.site['storageStream'] || this.site['count']) 351 | { 352 | //When partial-load and if the count and offset is not equal to the original one 353 | //'http channel Listener OnDataAvailable contract violation' warning will be fired, but that's all right nsHttpChannel will fix it. 354 | this.originalListener.onDataAvailable(request, context, this.site['storageStream'].newInputStream(0), 0, this.site['count']); 355 | } 356 | else 357 | { 358 | //Ignore 359 | this.originalListener.onDataAvailable(request, context, inputStream, offset, count); 360 | } 361 | } 362 | } 363 | }; 364 | 365 | // register observer 366 | var y = new YoukuAntiADs(); 367 | if(location == 'chrome://browser/content/browser.xul') { 368 | y.register(); 369 | } 370 | 371 | // unregister observer 372 | window.addEventListener('unload', function() { 373 | if(location == 'chrome://browser/content/browser.xul') { 374 | y.unregister(); 375 | } 376 | }); 377 | })(); -------------------------------------------------------------------------------- /swf/iqiyi5.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiayiming/FireLocalSWF/de53b738f882d80098382900ada713f30eb5bc3d/swf/iqiyi5.swf -------------------------------------------------------------------------------- /swf/iqiyi_out.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiayiming/FireLocalSWF/de53b738f882d80098382900ada713f30eb5bc3d/swf/iqiyi_out.swf -------------------------------------------------------------------------------- /swf/ku6.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiayiming/FireLocalSWF/de53b738f882d80098382900ada713f30eb5bc3d/swf/ku6.swf -------------------------------------------------------------------------------- /swf/ku6_out.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiayiming/FireLocalSWF/de53b738f882d80098382900ada713f30eb5bc3d/swf/ku6_out.swf -------------------------------------------------------------------------------- /swf/letvsdk.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiayiming/FireLocalSWF/de53b738f882d80098382900ada713f30eb5bc3d/swf/letvsdk.swf -------------------------------------------------------------------------------- /swf/loader.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiayiming/FireLocalSWF/de53b738f882d80098382900ada713f30eb5bc3d/swf/loader.swf -------------------------------------------------------------------------------- /swf/player.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiayiming/FireLocalSWF/de53b738f882d80098382900ada713f30eb5bc3d/swf/player.swf -------------------------------------------------------------------------------- /swf/pptv.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiayiming/FireLocalSWF/de53b738f882d80098382900ada713f30eb5bc3d/swf/pptv.swf -------------------------------------------------------------------------------- /swf/sohu_live.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiayiming/FireLocalSWF/de53b738f882d80098382900ada713f30eb5bc3d/swf/sohu_live.swf -------------------------------------------------------------------------------- /swf/tudou.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jiayiming/FireLocalSWF/de53b738f882d80098382900ada713f30eb5bc3d/swf/tudou.swf --------------------------------------------------------------------------------