Kongregate Flash games fixer

You can now chose between Flash and SuperNova to play Flash games on Kongregate!

目前為 2022-02-05 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Kongregate Flash games fixer
// @version      3.0
// @author       Matrix4348
// @namespace    https://greasyfork.org/users/4818
// @description  You can now chose between Flash and SuperNova to play Flash games on Kongregate!
// @license      MIT
// @match        *://*.konggames.com/games/*/*/frame/*
// @match        *://www.kongregate.com/games/*/*
// @grant        none
// ==/UserScript==

// Iframes part. The script must be limited to Flash iframes (the URL for the html games iframes look a bit different, but there may be some exceptions), so we will check if the iframe includes the variable kong_flash_variables.
if ((document.URL.search("/frame/")>-1)&(document.body.innerHTML.search("kong_flash_variables")>-1)){

    // First, we need to extract the link to the swf (the game file) and a few other things.
    var file_url0, file_url, file_url_base;
    var SNwidth, SNheight, my_bgcolor;
    var scripts=document.getElementsByTagName("script");
    for(var i=0; i<scripts.length;i++) {var script_text=scripts[i].text;
                                        var url_text;
                                        if(script_text.indexOf("game_swf")!== -1) {
                                            url_text=String(script_text.match(/game_swf\"\:\"(.*?)\"\,\"game_url/g));
                                            file_url0="https://"+decodeURIComponent(url_text.substring(17,(url_text.length/2)-11));

                                            // Background color parameter for swf injection.
                                            my_bgcolor=script_text.substring(script_text.search("bgcolor")+10,script_text.search("bgcolor")+17);

                                            // Values for the SuperNova part. Note that they will only be correctly defined if they have three digits, which should always be the case.
                                            SNwidth=script_text.substring(script_text.search("width")+7,script_text.search("width")+10);
                                            SNheight=script_text.substring(script_text.search("height")+8,script_text.search("height")+11);

                                            break;
                                        }
                                        else if(script_text.indexOf("swfurl")!== -1) {
                                            url_text=String(script_text.match(/swfurl\"\:\"(.*?)\"\,\"flashvars/g));
                                            file_url0=decodeURI(url_text.substring(9,url_text.length-12));

                                            // Background color parameter for swf injection.
                                            my_bgcolor=script_text.substring(script_text.search("bgcolor")+10,script_text.search("bgcolor")+17);

                                            // Values for the SuperNova part. Note that they will only be correctly defined if they have three digits, which should always be the case.
                                            SNwidth=script_text.substring(script_text.search("width")+7,script_text.search("width")+10);
                                            SNheight=script_text.substring(script_text.search("height")+8,script_text.search("height")+11);

                                            break;
                                        };
                                       };
    file_url=file_url0.substring(file_url0.search("//"),file_url0.length-1);
    file_url_base="http:"+file_url.substring(0,file_url.search("/live/")+6);

    // Then, we build the functions that will load the games.
    function more_players(){
        var a=document.createElement("script");
        a.id="More choice";
        a.type="text/javascript";
        // IMPORTANT: The checkParams function (originally present in the webpage) inputs the flashvars into kong_flash_variables.
        a.innerHTML=
    `//<![CDATA[

    FlashLoader = {
        loadGame: function(urlOptions) {
            var swf_location = "`+file_url+`";
            var swfobject_flash_vars = {};
            if(typeof(kong_flash_variables) == "object"){
                for(var k in kong_flash_variables){
                    swfobject_flash_vars[k] = encodeURIComponent(kong_flash_variables[k]);
                }
            }
            swfobject_flash_vars.kongregate_flash_postmessage=true; // USEFUL! This line, alone, makes the score submit again... for a few games (Epic Coaster, Mission in Space: the lost colony)!
            if(document.getElementById("game_wrapper").firstDescendant()!=null){document.getElementById("game_wrapper").firstDescendant().remove();};
            var d=document.createElement("div");
            d.id="gamediv";
            document.getElementById("game_wrapper").appendChild(d);
            swfobject.embedSWF(swf_location, "gamediv","100%","100%","6","/flash/expressInstall.swf",swfobject_flash_vars,{"bgcolor":"`+my_bgcolor+`","allownetworking":"all","allowscriptaccess":"always","base":"`+file_url_base+`"},{});
        }
    }

    function play_with_Flash(urlOptions) {
        if (!urlOptions) {
            urlOptions = '';
        }
        FlashLoader.loadGame(urlOptions);
        document.fire('game:activated');
    };

    var SNloadGame=function(A){
        var SNoptions = {
            "swfurl" : "http:`+file_url+`",
            "flashvars":{},
            "title" : ttgArgs.game_title,
            "width" : `+SNwidth+`,
            "height" : `+SNheight+`
                };
        if((typeof(kong_flash_variables) === 'object')&(typeof(supernova)==='object')){
            SNoptions.flashvars = $j.param(kong_flash_variables);
            if(document.getElementById("game_wrapper").firstDescendant()!=null){document.getElementById("game_wrapper").firstDescendant().remove();};
            var d=document.createElement("div");
            d.id="gamediv";
            document.getElementById("game_wrapper").appendChild(d);
            SNoptions.el = document.querySelector('#gamediv');
            supernova.launch(SNoptions);
            supernova.openGame(SNoptions);
            setTimeout(function(){delete SNloadGame;},1);
        }
        else if(A){setTimeout(function(B){SNloadGame(B);},10000,A--);}
        else{setTimeout(function(){delete SNloadGame;},1);}
    };

        function play_with_SuperNova(){ SNloadGame(10); };

        function play_with_Ruffle(){ // If it does not work, try also putting the instructions inside an onload parameters of ruffle.js, instead of loading ruffle.js, then another script.
            var r=document.createElement("script");
            r.type="text/javascript";
            r.src=""; // Sadly, the script must be on the Kongregate servers... Curse on that same-origin policy!
            document.body.appendChild(r);
            var swf_location = "`+file_url+`";
            var swfobject_flash_vars = {};
            if(typeof(kong_flash_variables) == "object"){
                for(var k in kong_flash_variables){
                    swfobject_flash_vars[k] = encodeURIComponent(kong_flash_variables[k]);
                }
            }
            if(document.getElementById("game_wrapper").firstDescendant()!=null){document.getElementById("game_wrapper").firstDescendant().remove();};
            var RandomFunctionName=function(A){
                if(window.RufflePlayer!=null){
                    window.RufflePlayer.config = {
                        "publicPath": undefined,
                        "contextMenu": true,
                        "showSwfDownload": true,
                        "menu": true,
                        "quality": "high",
                    };
                    const ruffle = window.RufflePlayer.newest();
                    const player = ruffle.createPlayer();
                    const container = document.getElementById("game_wrapper");
                    container.appendChild(player);
                    player.load({
                        url: swf_location,
                        parameters: swfobject_flash_vars,
                        allowScriptAccess: true
                    });
                    setTimeout(function(){delete RandomFunctionName;},1);
                }
                else if(A){setTimeout(function(B){RandomFunctionName(B);},10000,A--);}
                else{setTimeout(function(){delete RandomFunctionName;},1);}
            };
            RandomFunctionName(10);
        };

        function time_to_play(){
            // I do not know exactly what channel_id is for. All I know is that it is in the iframe link and elsewhere, and that is is some kind of hexadecimal character string.
            // Thus, the presence of a modified (and unusual) channel_id in the iframes' URL will be used to tell which player we want to use.
            // Moreover, changing it only in the URL SEEMS not to change the value used for the flashvars.

            // If we want the game to load with Flash:
            if(document.URL.search("me-wanna-Flash")>-1){ play_with_Flash(); }
            // If we want the game to load (properly!) with SuperNova:
            else if(document.URL.search("me-wanna-SuperNova")>-1){ play_with_SuperNova(); }
            // If we want the game to load with Ruffle:
            else if(document.URL.search("me-wanna-Ruffle")>-1){ play_with_Ruffle(); }
            // When the iframe loads normally (without a modified channel_id):
            else{
                function BrowVer(){ua=navigator.userAgent; return {Browser:ua.substring(ua.lastIndexOf(" ")+1,ua.lastIndexOf("/")),Version:ua.substring(ua.lastIndexOf("/")+1,ua.length)}};
                var b=BrowVer.Browser, v=BrowVer.Version;
                function FlashSupport(){
                   var np=navigator.plugins, npl=np.length;
                   for(var k=0;k<npl;k++){ if(np[k].name=="Shockwave Flash"){return true}; }
                   return false;
                };

                if(navigator.userAgent.search("Windows")==-1){ play_with_Flash(); } // Because SuperNova only works on Windows.
                else if(FlashSupport()==false){ play_with_SuperNova(); }
                else if(FlashSupport()==true){ play_with_Flash(); }

                else if((b=="Edg")||(b=="Chrome")||(b=="Safari")){ play_with_SuperNova(); } // Useless but
                else if((b=="Basilisk")||(b=="PaleMoon")){ play_with_Flash(); }             // could be useful
                else if((b=="Firefox")||(v<85)){ play_with_Flash();  }                      // in case of
                else if((b=="Firefox")||(v>=85)){ play_with_SuperNova();  }                 // a Ruffle
                else { play_with_Flash(); }                                                 // implementation.
            }
        };
        time_to_play();

        //]]>`;
        document.body.appendChild(a);
    };
    more_players();
}

// Game pages part. Only for Flash games, so I will make sure that active_user.gameType()="flash".
// I will make two "if" loops instead of one to avoid an error message in the console tab (even though this message would not break anything).
else if (document.URL.search("www.kongregate.com/games/")>-1){
    if(active_user.gameType()=="flash"){
        // Useful variables.
        var urlstart=document.URL.substring(0,document.URL.search("://"));

        var my_game_version, my_svid, my_game_width, my_game_height, my_game_left, my_game_top;
        var game_scripts=document.getElementById("game").getElementsByTagName("script");
        for(var j=0; j<game_scripts.length;j++) {var game_script_text=game_scripts[j].text;
                                                 if((game_script_text.indexOf("game_version")!== -1)&(game_script_text.indexOf("svid")!== -1)) {
                                                     my_game_version=game_script_text.substring(game_script_text.search("game_version")+14,game_script_text.search("flash_var_prefix")-2);
                                                     my_svid=game_script_text.substring(game_script_text.search("svid")+7,game_script_text.search("game_type")-3);
                                                     my_game_width=game_script_text.substring(game_script_text.search("game_width")+12,game_script_text.search("game_height")-2);
                                                     my_game_height=game_script_text.substring(game_script_text.search("game_height")+13,game_script_text.search("max_game_width")-2);
                                                     my_game_left=game_script_text.substring(game_script_text.search("game_left")+11,game_script_text.search("game_top")-2);
                                                     my_game_top=game_script_text.substring(game_script_text.search("game_top")+10,game_script_text.search("iframe_class")-2);
                                                     break;
                                                 }
                                                };

        // What will be inserted in the webpage, to load the different iframes we will use.

        // I do not know what channel_id is used for, nor weither or not it is relevant as it changes everytime the game page is reloaded, but yet appears in the iframe link.
        // All I know is that is is some kind of hexadecimal characters string.
        // Thus, I will replace it with values that it will never take so that the script can detect which player it should load the game with.

        var ic=document.createElement("script");
        ic.id="iframe constructors";
        ic.innerHTML=
            `//<![CDATA[
              FlashLoader = {
          loadGame: function(urlOptions) {
                  new GameIframe({
                     "auto_resize":null,
                     "iframe_url":"`+urlstart+`"+"://game"+active_user.gameId()+".konggames.com"+active_user.gamePath()+'/frame/' + "me-wanna-Flash" + '/?kongregate_host=www.kongregate.com',
                     "alternate_game_file_url":null,
                     "game_width":`+my_game_width+`,
                     "game_height":`+my_game_height+`,
                     "max_game_width":null,
                     "max_game_height":null,
                     "game_left":`+my_game_left+`,
                     "game_top":`+my_game_top+`,
                     "iframe_class":"dont_hide",
                     "host":"`+urlstart+`"+"://www.kongregate.com",
                     "api_host":"`+urlstart+`"+"://api.kongregate.com",
                     "api_path":"https://chat.kongregate.com/flash/API_AS3_d43c4b859e74432475c1627346078677.swf",
                     "preview":false,
                     "game_permalink":active_user.gamePermalink(),
                     "game_id":active_user.gameId(),
                     "game_url":"http://www.kongregate.com"+active_user.gamePath(),
                     "game_version":`+my_game_version+`,
                     "flash_var_prefix":"kv_",
                     "post_message":true,
                     "iframe_host":"`+urlstart+`"+"://game"+active_user.gameId()+".konggames.com",
                     "game_host":"`+urlstart+`"+"://chat.kongregate.com",
                     "channel_id":encodeURIComponent(channel_id),
                     "svid":"`+my_svid+`",
                     "game_type":"flash"
                     },
                  urlOptions, channel_id).createGameIframeElement();

          }
        }

      function LoadFlashIframe(urlOptions) {
        if (!urlOptions) {
          urlOptions = '';
        }
        FlashLoader.loadGame(urlOptions);
        document.fire('game:activated');
      };

      SuperNovaLoader = {
          loadGame: function(urlOptions) {
                  new GameIframe({
                     "auto_resize":null,
                     "iframe_url":"`+urlstart+`"+"://game"+active_user.gameId()+".konggames.com"+active_user.gamePath()+'/frame/' + "me-wanna-SuperNova" + '/?kongregate_host=www.kongregate.com',
                     "alternate_game_file_url":null,
                     "game_width":`+my_game_width+`,
                     "game_height":`+my_game_height+`,
                     "max_game_width":null,
                     "max_game_height":null,
                     "game_left":`+my_game_left+`,
                     "game_top":`+my_game_top+`,
                     "iframe_class":"dont_hide",
                     "host":"`+urlstart+`"+"://www.kongregate.com",
                     "api_host":"`+urlstart+`"+"://api.kongregate.com",
                     "api_path":"https://chat.kongregate.com/flash/API_AS3_d43c4b859e74432475c1627346078677.swf",
                     "preview":false,
                     "game_permalink":active_user.gamePermalink(),
                     "game_id":active_user.gameId(),
                     "game_url":"http://www.kongregate.com"+active_user.gamePath(),
                     "game_version":`+my_game_version+`,
                     "flash_var_prefix":"kv_",
                     "post_message":true,
                     "iframe_host":"`+urlstart+`"+"://game"+active_user.gameId()+".konggames.com",
                     "game_host":"`+urlstart+`"+"://chat.kongregate.com",
                     "channel_id":encodeURIComponent(channel_id),
                     "svid":"`+my_svid+`",
                     "game_type":"flash"
                     },
                  urlOptions, channel_id).createGameIframeElement();

          }
        }

      function LoadSuperNovaIframe(urlOptions) {
        if (!urlOptions) {
          urlOptions = '';
        }
        SuperNovaLoader.loadGame(urlOptions);
        document.fire('game:activated');
      };

      RuffleLoader = {
          loadGame: function(urlOptions) {
                  new GameIframe({
                     "auto_resize":null,
                     "iframe_url":"`+urlstart+`"+"://game"+active_user.gameId()+".konggames.com"+active_user.gamePath()+'/frame/' + "me-wanna-Ruffle" + '/?kongregate_host=www.kongregate.com',
                     "alternate_game_file_url":null,
                     "game_width":`+my_game_width+`,
                     "game_height":`+my_game_height+`,
                     "max_game_width":null,
                     "max_game_height":null,
                     "game_left":`+my_game_left+`,
                     "game_top":`+my_game_top+`,
                     "iframe_class":"dont_hide",
                     "host":"`+urlstart+`"+"://www.kongregate.com",
                     "api_host":"`+urlstart+`"+"://api.kongregate.com",
                     "api_path":"https://chat.kongregate.com/flash/API_AS3_d43c4b859e74432475c1627346078677.swf",
                     "preview":false,
                     "game_permalink":active_user.gamePermalink(),
                     "game_id":active_user.gameId(),
                     "game_url":"http://www.kongregate.com"+active_user.gamePath(),
                     "game_version":`+my_game_version+`,
                     "flash_var_prefix":"kv_",
                     "post_message":true,
                     "iframe_host":"`+urlstart+`"+"://game"+active_user.gameId()+".konggames.com",
                     "game_host":"`+urlstart+`"+"://chat.kongregate.com",
                     "channel_id":encodeURIComponent(channel_id),
                     "svid":"`+my_svid+`",
                     "game_type":"flash"
                     },
                  urlOptions, channel_id).createGameIframeElement();

          }
        }

      function LoadRuffleIframe(urlOptions) {
        if (!urlOptions) {
          urlOptions = '';
        }
        RuffleLoader.loadGame(urlOptions);
        document.fire('game:activated');
      };

//]]>`;
        document.getElementById("game").appendChild(ic);

        // Let's make some shiny buttons!
        var s=document.createElement("script"), ButtonMaker;
        s.type="text/javascript";
        s.id="Shiny buttons";
        document.head.appendChild(s.appendChild(document.createTextNode('('+function(){
            ButtonMaker=function(x){
                var ql=document.getElementById("quicklinks");
                if(holodeck&&LoadFlashIframe&&ql!==null){
                    // Flash button
                    var FlashButton=document.createElement('li');
                    FlashButton.id="Button to (re)load with Flash";
                    FlashButton.innerHTML='<a href="#" onclick="LoadFlashIframe(); return false">Flash</a>';
                    ql.insert(FlashButton,ql.firstChild);
                    // SuperNova button
                    var SuperNovaButton=document.createElement('li');
                    SuperNovaButton.id="Button to (re)load with SuperNova";
                    SuperNovaButton.innerHTML='<a href="#" onclick="LoadSuperNovaIframe(); return false">SuperNova</a>';
                    ql.insert(SuperNovaButton,ql.firstChild);
                    // Ruffle button
                    var RuffleButton=document.createElement('li');
                    RuffleButton.id="Button to (re)load with Ruffle";
                    RuffleButton.innerHTML='<a href="#" onclick="LoadRuffleIframe(); return false">Ruffle</a>';
                    //ql.insert(RuffleButton,ql.firstChild); //UNHIDE IF THE RUFFLE SCRIPT IS ONE DAY, BY SOME MIRACLE, UPLOADED TO THE KONGREGATE SERVERS.
                    // No more buttons
                    setTimeout(function(){delete ButtonMaker;},1);
                }
                else if(x){setTimeout(function(y){ButtonMaker(y);},10000,x--);}
                else{setTimeout(function(){delete ButtonMaker;},1);}
            };
            ButtonMaker(10);
        }+')()')).parentNode);

    }
};