您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Manages Wall Posts for Various FB Games
当前为
// ==UserScript== // @name FB Wall Manager // @namespace MerricksdadWallManager // @description Manages Wall Posts for Various FB Games // @include http*://www.facebook.com/lists/* // @license http://creativecommons.org/licenses/by-nc-nd/3.0/us/ // @grant GM_setValue // @grant GM_getValue // @grant GM_xmlhttpRequest // @grant GM_registerMenuCommand // @grant GM_addStyle // @grant GM_log // @grant GM_openInTab // @grant GM_getResourceURL // @version 4.0.0.4 // @copyright Charlie Ewing except where noted // @require https://gf.qytechs.cn/scripts/416-wm-common-library/code/WM%20Common%20Library.user.js // @require https://gf.qytechs.cn/scripts/417-wm-debug-console/code/WM%20Debug%20Console.user.js // @require https://gf.qytechs.cn/scripts/418-js-forms-library-b/code/JS%20Forms%20Library%20B.user.js // @require https://gf.qytechs.cn/scripts/419-wm-config-interface/code/WM%20Config%20Interface.user.js // @require https://gf.qytechs.cn/scripts/6908-wm-host-object/code/WM%20Host%20Object.js // @require https://gf.qytechs.cn/scripts/6907-wm-user-console-object/code/WM%20User%20Console%20Object.js // @require https://gf.qytechs.cn/scripts/6906-wm-sidekick-docking-object/code/WM%20Sidekick%20Docking%20Object.js // @require https://gf.qytechs.cn/scripts/6905-wm-collector-object/code/WM%20Collector%20Object.js // @require https://gf.qytechs.cn/scripts/6904-wm-dynamic-grabber-object/code/WM%20Dynamic%20Grabber%20Object.js // @require https://gf.qytechs.cn/scripts/6899-wm-test-object/code/WM%20Test%20Object.js // @require https://gf.qytechs.cn/scripts/6898-wm-feed-manager-objects/code/WM%20Feed%20Manager%20Objects.js // @require https://gf.qytechs.cn/scripts/6897-wm-friend-tracker-objects/code/WM%20Friend%20Tracker%20Objects.js // @require https://gf.qytechs.cn/scripts/6896-wm-rules-manager-objects/code/WM%20Rules%20Manager%20Objects.js // @require https://gf.qytechs.cn/scripts/6895-wm-app-object/code/WM%20App%20Object.js // @require https://gf.qytechs.cn/scripts/6894-wm-post-object/code/WM%20Post%20Object.js // @resource IconSheet http://i.imgur.com/sLxzUA6.png // ==/UserScript== // Based on script built by Joe Simmons in Farmville Wall Manager (function() { //*************************************************************************************************************************************** //***** Preload //*************************************************************************************************************************************** //dont run in iframes try { //this does not mean we are using GM's unsafe window var unsafeWindow = unsafeWindow || window.wrappedJSObject || window; if (unsafeWindow.frameElement != null) { alert("unsafe window"); return; } } catch(e) {log("preload: "+e);} //*************************************************************************************************************************************** //***** Debug Object //*************************************************************************************************************************************** if (debug) { //from script WM_Debug_Console.user.js debug.init(); if (debug.initialized) log("Debug Console Initialized"); } //*************************************************************************************************************************************** //***** Globals //*************************************************************************************************************************************** //returns the current date-time in unix format, not localized WM.__defineGetter__("currentTime",function(){try{ return timeStamp(); }catch(e){log("WM.currentTime: "+e);}}); //returns the appID of the selected app tab on the collection panel, or 'all' if 'Show All' is selected WM.__defineGetter__("currentAppTab",function(){try{ var tabCtrl=WM.console.collectTabControl; if (tabCtrl||null) { var tab = tabCtrl._selectedTab; if (tab||null) return tab.appFilter; } return "all"; }catch(e){log("WM.currentAppTab: "+e);}}); var sandbox=this; //*************************************************************************************************************************************** //***** new graph functions //*************************************************************************************************************************************** this.Graph={ posts:{}, //"post_id":1 or null userID:null, userName:null, userAlias:null, fetchTimeout: 30, likePost: function(postObj,params){ //detect state of like link var subNode = postObj.likeLink; if (subNode) { var isLiked = subNode.getAttribute('data-ft').parseJSON()['tn'] == "?"; if (!isLiked) { click(subNode); } else { //already liked } if (params.callback) params.callback(postObj); } postObj.pageNode.style.display="block"; }, unlikePost: function(postObj){ //detect state of like link var subNode = postObj.likeLink; if (subNode) { var isLiked = subNode.getAttribute('data-ft').parseJSON()['tn'] == "?"; if (isLiked) { click(subNode); } else { //already not liked } if (params.callback) params.callback(postObj); } postObj.pageNode.style.display="block"; }, commentPost: function(postObj,comment){ debug.print("commenting is disabled in WM version 4 until further notice"); /* var subNode = postObj.commentLink; if (subNode) { click(subNode); setTimeout(function(){typeText(comment);},1000); } */ }, getCurrentUser: function(params){ var node = selectSingleNode("//img[starts-with(@id,'profile_pic_header_')]"); this.userID = node.id.split("profile_pic_header_")[1]; this.userName = node.parentNode.childNodes[1].textContent; //will only get first name this.userAlias = node.parentNode.href.split("facebook.com/")[1]; }, validatePost: function(params){ var post=params.post; var callback=params.callback; var isOlder=params.next; //log("Graph.validatePost()",{level:1}); //exclude non-app posts and posts with no action links //if (!exists(post.actions||null) || !exists(post.application)) return; //exclude posts with less than like and comment and which have no link //if (!(post.actions.length>=2) || !exists(post.link)) return; var postID=post["post_id"]||post["id"]; //exclude posts already in our repository if (exists(Graph.posts[postID])) return; //store a reference to this post Graph.posts[postID]=1; //send the post back to the callback function here if (callback) setTimeout(function(){callback(post,isOlder);},0); }, fetchPosts: function(params){ //check for paused fetching if (WM.fetchPaused && !params.bypassPause) return; params = params||{}; params.callback = params.callback||WM.validatePost; //default callback if not specified //reads post data from the page var postNodes = selectNodes("//div[starts-with(@class,'_4-u2 mbm _5jmm _5pat _5v3q') and not(contains(@class,'foundWM'))]"); //translate post dom to useable data var retPosts = {}; if (postNodes.snapshotLength) { //debug.print (postNodes.snapshotLength + " post nodes found"); for (var i=0,node;(node=postNodes.snapshotItem(i));i++) { var post = {}; post.pageNode = node.childNodes[0].parentNode; //post id try{ var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//form//input[contains(@value,'target_fbid')]",{node:node}); post.post_id = subNode.getAttribute('value').parseJSON()['target_fbid']; } catch (e){ //debug.print("cound not locate postID " + node.id); continue; } /*//post QID try{ post.qid = post.pageNode.getAttribute('data-ft').parseJSON()['qid']; } catch (e){ debug.print("cound not locate post qid " + node.id); //continue; }*/ //from try{ var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//span[contains(@class,'fwb fcg')]/a[contains(@data-hovercard,'user.php')]",{node:node}); post.source_id = subNode.getAttribute('data-hovercard').split('user.php?id=')[1].split("&")[0]; post.fromName = subNode.textContent; } catch (e){ //debug.print("cound not locate fromID " + node.id); continue; } //exclude posts already in our repository if (Graph.posts[post.source_id+"_"+post.post_id]!=1) { //appID try{ var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]",{node:node}); post.app_id = subNode.getAttribute('data-gt').parseJSON()['appid'].toString(); if (!(WM.apps[post.app_id]||null)) continue; } catch (e){ //debug.print("cound not locate appID: " + node.id); continue; } //created time try{ var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//abbr[contains(@class,'timestamp')]",{node:node}); post.created_time = subNode.getAttribute('data-utime'); } catch (e){ //debug.print("cound not locate created time " + node.id); continue; } //message try{ var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//div[contains(@class,'_5pbx userContent')]",{node:node}); post.message = subNode.textContent; } catch (e){ //debug.print("cound not locate message " + node.id); //continue; //don't break if this does not exist post.message=""; } //title try{ var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//div[contains(@class,'_6m6')]/a",{node:node}); post.title = subNode.textContent; } catch (e){ //debug.print("cound not locate title " + node.id); continue; } //description try{ var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//div[contains(@class,'_6lz _6mb')]",{node:node}); post.description = subNode.textContent; } catch (e){ //debug.print("cound not locate description " + node.id); continue; } //caption try{ var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//div[contains(@class,'_6m7')]",{node:node}); post.caption = subNode.textContent; } catch (e){ //debug.print("cound not locate caption " + node.id); continue; } //picture try{ var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//div[contains(@class,'fbStoryAttachmentImage')]/img",{node:node}); post.picture = subNode.src; } catch (e){ //debug.print("cound not locate picture " + node.id); continue; } //link href try{ var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//form//div[contains(@class,'_5pcp _5vsi')]/div/a",{node:node}); //put our mouse over it first to force it to update link data mouseover(subNode); post.linkHref = subNode.href; post.linkText = subNode.textContent; } catch (e){ //debug.print("cound not locate link " + node.id); continue; } //like button try{ var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//div[contains(@class,'_5pcp _5vsi')]/div/span/a[contains(@data-reactid,'.')]",{node:node}); post.isLiked = subNode.getAttribute('data-ft').parseJSON()['tn'] == "?"; post.likeLink = subNode; } catch (e){ //debug.print("cound not locate likes " + node.id); continue; } //comment section try{ var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//label[contains(@class,'uiLinkButton comment_link')]/input",{node:node}); post.commentLink = subNode; var subNode = selectSingleNode("./div[starts-with(@class,'userContentWrapper')]//div[contains(@class,'_209g _2vxa')]/span/br",{node:node}); post.commentNode = subNode; } catch (e){ //debug.print("cound not locate comments " + node.id); continue; } node.className += " foundWM"; if (post.isLiked) { post.pageNode.style.display="block"; } //debug.print([post.app_id, post.source_id, post.post_id, post.fromName, post.created_time, post.title, post.caption, post.description, post.picture, post.linkHref, post.linkText, post.isLiked]); //store a reference to this post Graph.posts[post.source_id+"_"+post.post_id]=1; //send the post back to the callback function here params.callback(post); } } } else { //debug.print ("no post nodes found"); }; } }; Graph.getCurrentUser(); //*************************************************************************************************************************************** //***** Immediate //*************************************************************************************************************************************** log("Script: WM initialized",{level:0}); // section for reclaiming memory and stopping memory leaks this.newIntv=null; //refresh interval this.oldIntv=null; //refresh interval this.procIntv=null; //process interval this.cleanIntv=null; //post removal interval this.hbIntv=null; //global heartbeat interval this.refreshIntv=null; //global page refresh interval this.olderLimit=day; //default 1 day //mutation observer var observer = new MutationObserver(function(mutations) { //mutations.forEach(function(mutation) { //console.log(mutation.type); //only process new nodes if console is ready for them if (!WM.console.initialized) return; //when any page mutation occurs, run our post detector Graph.fetchPosts({ callback:WM.validatePost }); }); //cleanup function var cleanup=function() {try{ //destroy intervals if (newIntv) window.clearInterval(newIntv); if (oldIntv) window.clearInterval(oldIntv); if (procIntv) window.clearInterval(procIntv); if (cleanIntv) window.clearInterval(cleanIntv); if (hbIntv) window.clearInterval(hbIntv); if (refreshIntv) window.clearInterval(refreshIntv); refreshIntv = oldIntv = newIntv = procIntv = cleanIntv = hbIntv = null; //close the sidekick tabs WM.collector.closeAll(); //remove this event listener window.removeEventListener("beforeunload", cleanup, false); window.removeEventListener("message", WM.receiveSidekickMessage, false); window.removeEventListener("resize", WM.onWindowResize, false); observer.disconnect(); //clean up memory WallManager=null; Graph=null; jsForms=null; olderLimit=null; opts=null; quickOpts=null; }catch(e){log("cleanup: "+e);}} window.addEventListener("beforeunload", cleanup, false); window.addEventListener("resize", WM.onWindowResize, false); observer.observe(document.body,{ attributes: true, childList: true, characterData: true }); addGlobalStyle(".foundWM {background-color:green; display:none;}\n","styleDebugTemp"); //start it up WM.run(); })(); // anonymous function wrapper end /* recent changes 4.0.0.0: moved many object's code to their own files 4.0.0.3: fixed autolike fixed undefined post type debugging 4.0.0.4: fixed fetching pause fixed fetching manually added autorefresh page timer to options menu updated rules manager refreshBrowser function to check for options menu open, or posts being collected removed fetching older posts functions changed rules manager fetch newer posts to fetch visible posts, for use when auto fetch is paused */
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址