Kongregate Flash games fixer

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

Verze ze dne 08. 02. 2022. Zobrazit nejnovější verzi.

  1. // ==UserScript==
  2. // @name Kongregate Flash games fixer
  3. // @version 3.2.2
  4. // @author Matrix4348
  5. // @namespace https://greasyfork.org/users/4818
  6. // @description You can now chose between Flash and SuperNova to play Flash games on Kongregate!
  7. // @license MIT
  8. // @match *://*.konggames.com/games/*/*/frame/*
  9. // @match *://www.kongregate.com/games/*/*
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. // 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.
  14. if ((document.URL.search("/frame/")>-1)&(document.body.innerHTML.search("kong_flash_variables")>-1)){
  15.  
  16. // First, we need to extract the link to the swf (the game file) and a few other things.
  17. var file_url0, file_url, file_url_base; // Basic URL.
  18. var my_first_link, my_second_link, blablabla, GameShellAPI; // For loading the games in a gameshell when they should, because in these cases the gameshell is required for submitting scores.
  19. var SNwidth, SNheight, my_bgcolor; // Parameters.
  20. var scripts=document.getElementsByTagName("script");
  21. for(var i=0; i<scripts.length;i++) {var script_text=scripts[i].text;
  22. var url_text;
  23. if(script_text.indexOf("game_swf")!== -1) { //Gameshell dans swfurl et vrai lien dans game_swf.
  24. url_text=String(script_text.match(/game_swf\"\:\"(.*?)\"\,\"game_url/g));
  25. file_url0="https://"+decodeURIComponent(url_text.substring(17,(url_text.length/2)-11));
  26.  
  27. // Background color parameter for swf injection.
  28. my_bgcolor=script_text.substring(script_text.search("bgcolor")+10,script_text.search("bgcolor")+17);
  29.  
  30. // Flash, game shell and API.
  31. blablabla=String(script_text.match(/swfurl\"\:\"(.*?)\"\,\"flashvars/g));
  32. my_first_link=blablabla.substring(blablabla.search("//"),blablabla.search(".swf")+4);
  33. my_second_link=encodeURIComponent("http:"+file_url0.substring(file_url0.search("//"),file_url0.length)); // HTTPS WILL NOT MAKE THE API LOAD!
  34. var blabla=String(script_text.match(/kongregate_api_path(.*?)\"title/g));
  35. GameShellAPI=decodeURIComponent(blabla.substring(blabla.search("flash")-3,blabla.search(".swf")+4));
  36.  
  37. // Values for the SuperNova part. Note that they will only be correctly defined if they have three digits, which should always be the case.
  38. SNwidth=script_text.substring(script_text.search("width")+7,script_text.search("width")+10);
  39. SNheight=script_text.substring(script_text.search("height")+8,script_text.search("height")+11);
  40.  
  41. break;
  42. }
  43. else if(script_text.indexOf("swfurl")!== -1) {
  44. url_text=String(script_text.match(/swfurl\"\:\"(.*?)\"\,\"flashvars/g));
  45. file_url0=decodeURIComponent(url_text.substring(9,url_text.length-12));
  46.  
  47. // Background color parameter for swf injection.
  48. my_bgcolor=script_text.substring(script_text.search("bgcolor")+10,script_text.search("bgcolor")+17);
  49.  
  50. // Flash, game shell and API (even though, in this part of the loop, games do not need game shells).
  51. my_first_link=file_url0.substring(file_url0.search("//"),file_url0.length);
  52. my_second_link="";
  53. GameShellAPI="";
  54.  
  55. // Values for the SuperNova part. Note that they will only be correctly defined if they have three digits, which should always be the case.
  56. SNwidth=script_text.substring(script_text.search("width")+7,script_text.search("width")+10);
  57. SNheight=script_text.substring(script_text.search("height")+8,script_text.search("height")+11);
  58.  
  59. break;
  60. };
  61. };
  62. file_url=file_url0.substring(file_url0.search("//"),file_url0.length);
  63. if (file_url.search("/live/")>-1){
  64. file_url_base="http:"+file_url.substring(0,file_url.search("/live/")+6);
  65. }
  66. else {
  67. file_url_base="http:"+file_url.substring(0,file_url.search("/game_files/")+22);
  68. };
  69.  
  70. // Then, we build the functions that will load the games.
  71. function more_players(){
  72. var a=document.createElement("script");
  73. a.id="More choice";
  74. a.type="text/javascript";
  75. // IMPORTANT: The checkParams function (originally present in the webpage) inputs most of the flashvars into kong_flash_variables.
  76. a.innerHTML=
  77. `//<![CDATA[
  78. FlashLoader = {
  79. loadGame: function(urlOptions) {
  80. var swf_location = "`+my_first_link+`";
  81. var swfobject_flash_vars = {};
  82. if(typeof(kong_flash_variables) == "object"){
  83. for(var k in kong_flash_variables){
  84. swfobject_flash_vars[k] = encodeURIComponent(kong_flash_variables[k]);
  85. }
  86. }
  87. // Score API (re)activation part:
  88. swfobject_flash_vars.kongregate_flash_postmessage=true; // This line alone activates the API for a few (recent?) games.
  89. swfobject_flash_vars.api_path=swfobject_flash_vars.kongregate_api_path; // This one, combined with the previous one, will activate the API for most of the remaining ones.
  90. swfobject_flash_vars.api_host=swfobject_flash_vars.kongregate_api_host; // Needed? Useless?
  91. swfobject_flash_vars.game_url=swfobject_flash_vars.kongregate_game_url; // May be useless, or may reactivate API on games where we supposed it broken for good, who knows...
  92. swfobject_flash_vars.kongregate_stamp=swfobject_flash_vars.kongregate_game_auth_token; // May be useless, or may reactivate API on games where we supposed it broken for good, who knows...
  93. gameswfifgameshell="`+my_second_link+`";
  94. if(gameswfifgameshell.length!=0){
  95. swfobject_flash_vars.game_swf=gameswfifgameshell;
  96. swfobject_flash_vars.kongregate_api_path=encodeURIComponent("`+GameShellAPI+`"); // Yep, game shells need a different API file!
  97. swfobject_flash_vars.api_path=swfobject_flash_vars.kongregate_api_path;
  98. };
  99.  
  100. if(document.getElementById("game_wrapper").firstDescendant()!=null){document.getElementById("game_wrapper").firstDescendant().remove();};
  101. var d=document.createElement("div");
  102. d.id="gamediv";
  103. document.getElementById("game_wrapper").appendChild(d);
  104. 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+`"},{});
  105. }
  106. }
  107.  
  108. function play_with_Flash(urlOptions) {
  109. if (!urlOptions) {
  110. urlOptions = '';
  111. }
  112. FlashLoader.loadGame(urlOptions);
  113. document.fire('game:activated');
  114. };
  115.  
  116. var SNloadGame=function(A){
  117. var SNoptions = {
  118. "swfurl" : "http:`+file_url+`",
  119. "flashvars":{},
  120. "title" : ttgArgs.game_title,
  121. "width" : `+SNwidth+`,
  122. "height" : `+SNheight+`
  123. };
  124. if((typeof(kong_flash_variables) === 'object')&(typeof(supernova)==='object')){
  125. SNoptions.flashvars = $j.param(kong_flash_variables);
  126. if(document.getElementById("game_wrapper").firstDescendant()!=null){document.getElementById("game_wrapper").firstDescendant().remove();};
  127. var d=document.createElement("div");
  128. d.id="gamediv";
  129. document.getElementById("game_wrapper").appendChild(d);
  130. SNoptions.el = document.querySelector('#gamediv');
  131. supernova.launch(SNoptions);
  132. supernova.openGame(SNoptions);
  133. setTimeout(function(){delete SNloadGame;},1);
  134. }
  135. else if(A){setTimeout(function(B){SNloadGame(B);},10000,A--);}
  136. else{setTimeout(function(){delete SNloadGame;},1);}
  137. };
  138.  
  139. function play_with_SuperNova(){ SNloadGame(10); };
  140.  
  141. 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.
  142. var r=document.createElement("script");
  143. r.type="text/javascript";
  144. r.src=""; // Sadly, the script must be on the Kongregate servers... Curse on that same-origin policy!
  145. document.body.appendChild(r);
  146. var swf_location = "`+file_url+`";
  147. var swfobject_flash_vars = {};
  148. if(typeof(kong_flash_variables) == "object"){
  149. for(var k in kong_flash_variables){
  150. swfobject_flash_vars[k] = encodeURIComponent(kong_flash_variables[k]);
  151. }
  152. }
  153. // In case of activation: remember to add the same extra flashvars, like for Flash, so the API will work.
  154. if(document.getElementById("game_wrapper").firstDescendant()!=null){document.getElementById("game_wrapper").firstDescendant().remove();};
  155. var RandomFunctionName=function(A){
  156. if(window.RufflePlayer!=null){
  157. window.RufflePlayer.config = {
  158. "publicPath": undefined,
  159. "contextMenu": true,
  160. "showSwfDownload": true,
  161. "menu": true,
  162. "quality": "high",
  163. };
  164. const ruffle = window.RufflePlayer.newest();
  165. const player = ruffle.createPlayer();
  166. const container = document.getElementById("game_wrapper");
  167. container.appendChild(player);
  168. player.load({
  169. url: swf_location,
  170. parameters: swfobject_flash_vars,
  171. allowScriptAccess: true
  172. });
  173. setTimeout(function(){delete RandomFunctionName;},1);
  174. }
  175. else if(A){setTimeout(function(B){RandomFunctionName(B);},10000,A--);}
  176. else{setTimeout(function(){delete RandomFunctionName;},1);}
  177. };
  178. RandomFunctionName(10);
  179. };
  180.  
  181. function time_to_play(){
  182. // 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.
  183. // 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.
  184. // Moreover, changing it only in the URL SEEMS not to change the value used for the flashvars.
  185.  
  186. // If we want the game to load with Flash:
  187. if(document.URL.search("me-wanna-Flash")>-1){ play_with_Flash(); }
  188. // If we want the game to load (properly!) with SuperNova:
  189. else if(document.URL.search("me-wanna-SuperNova")>-1){ play_with_SuperNova(); }
  190. // If we want the game to load with Ruffle:
  191. else if(document.URL.search("me-wanna-Ruffle")>-1){ play_with_Ruffle(); }
  192. // When the iframe loads normally (without a modified channel_id):
  193. else{
  194. function BrowVer(){ua=navigator.userAgent; return {Browser:ua.substring(ua.lastIndexOf(" ")+1,ua.lastIndexOf("/")),Version:ua.substring(ua.lastIndexOf("/")+1,ua.length)}};
  195. var b=BrowVer.Browser, v=BrowVer.Version;
  196. function FlashSupport(){
  197. var np=navigator.plugins, npl=np.length;
  198. for(var k=0;k<npl;k++){ if(np[k].name=="Shockwave Flash"){return true}; }
  199. return false;
  200. };
  201.  
  202. if(navigator.userAgent.search("Windows")==-1){ play_with_Flash(); } // Because SuperNova only works on Windows.
  203. else if(FlashSupport()==false){ play_with_SuperNova(); }
  204. else if(FlashSupport()==true){ play_with_Flash(); }
  205.  
  206. else if((b=="Edg")||(b=="Chrome")||(b=="Safari")){ play_with_SuperNova(); } // Useless but
  207. else if((b=="Basilisk")||(b=="PaleMoon")){ play_with_Flash(); } // could be useful
  208. else if((b=="Firefox")||(v<85)){ play_with_Flash(); } // in case of
  209. else if((b=="Firefox")||(v>=85)){ play_with_SuperNova(); } // a Ruffle
  210. else { play_with_Flash(); } // implementation.
  211. }
  212. };
  213. var time_to_play_but_at_the_correct_time=function(a){
  214. if(activateGame._alreadyActivated){
  215. time_to_play();
  216. setTimeout(function(){delete time_to_play_but_at_the_correct_time;},1);
  217. }
  218. else if(a){setTimeout(function(b){time_to_play_but_at_the_correct_time(b);},10000,a--);}
  219. else{setTimeout(function(){delete time_to_play_but_at_the_correct_time;},1);}
  220. };
  221. time_to_play_but_at_the_correct_time(10);
  222.  
  223. //]]>`;
  224. document.body.appendChild(a);
  225. };
  226. more_players();
  227. }
  228.  
  229. // Game pages part. Only for Flash games, so I will make sure that active_user.gameType()="flash".
  230. // 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).
  231. else if (document.URL.search("www.kongregate.com/games/")>-1){
  232. if(active_user.gameType()=="flash"){
  233. // Useful variables.
  234. var urlstart=document.URL.substring(0,document.URL.search("://"));
  235.  
  236. var my_game_version, my_svid, my_game_width, my_game_height, my_game_left, my_game_top;
  237. var game_scripts=document.getElementById("game").getElementsByTagName("script");
  238. for(var j=0; j<game_scripts.length;j++) {var game_script_text=game_scripts[j].text;
  239. if((game_script_text.indexOf("game_version")!== -1)&(game_script_text.indexOf("svid")!== -1)) {
  240. my_game_version=game_script_text.substring(game_script_text.search("game_version")+14,game_script_text.search("flash_var_prefix")-2);
  241. my_svid=game_script_text.substring(game_script_text.search("svid")+7,game_script_text.search("game_type")-3);
  242. my_game_width=game_script_text.substring(game_script_text.search("game_width")+12,game_script_text.search("game_height")-2);
  243. my_game_height=game_script_text.substring(game_script_text.search("game_height")+13,game_script_text.search("max_game_width")-2);
  244. my_game_left=game_script_text.substring(game_script_text.search("game_left")+11,game_script_text.search("game_top")-2);
  245. my_game_top=game_script_text.substring(game_script_text.search("game_top")+10,game_script_text.search("iframe_class")-2);
  246. break;
  247. }
  248. };
  249.  
  250. // What will be inserted in the webpage, to load the different iframes we will use.
  251.  
  252. // 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.
  253. // All I know is that is is some kind of hexadecimal characters string.
  254. // 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.
  255.  
  256. var ic=document.createElement("script");
  257. ic.id="iframe constructors";
  258. ic.innerHTML=
  259. `//<![CDATA[
  260. FlashLoader = {
  261. loadGame: function(urlOptions) {
  262. new GameIframe({
  263. "auto_resize":null,
  264. "iframe_url":"`+urlstart+`"+"://game"+active_user.gameId()+".konggames.com"+active_user.gamePath()+'/frame/' + "me-wanna-Flash" + '/?kongregate_host=www.kongregate.com',
  265. "alternate_game_file_url":null,
  266. "game_width":`+my_game_width+`,
  267. "game_height":`+my_game_height+`,
  268. "max_game_width":null,
  269. "max_game_height":null,
  270. "game_left":`+my_game_left+`,
  271. "game_top":`+my_game_top+`,
  272. "iframe_class":"dont_hide",
  273. "host":"`+urlstart+`"+"://www.kongregate.com",
  274. "api_host":"`+urlstart+`"+"://api.kongregate.com",
  275. "api_path":"https://chat.kongregate.com/flash/API_AS3_d43c4b859e74432475c1627346078677.swf",
  276. "preview":false,
  277. "game_permalink":active_user.gamePermalink(),
  278. "game_id":active_user.gameId(),
  279. "game_url":"http://www.kongregate.com"+active_user.gamePath(),
  280. "game_version":`+my_game_version+`,
  281. "flash_var_prefix":"kv_",
  282. "post_message":true,
  283. "iframe_host":"`+urlstart+`"+"://game"+active_user.gameId()+".konggames.com",
  284. "game_host":"`+urlstart+`"+"://chat.kongregate.com",
  285. "channel_id":encodeURIComponent(channel_id),
  286. "svid":"`+my_svid+`",
  287. "game_type":"flash"
  288. },
  289. urlOptions, channel_id).createGameIframeElement();
  290.  
  291. }
  292. }
  293.  
  294. function LoadFlashIframe(urlOptions) {
  295. if (!urlOptions) {
  296. urlOptions = '';
  297. }
  298. FlashLoader.loadGame(urlOptions);
  299. document.fire('game:activated');
  300. };
  301.  
  302. SuperNovaLoader = {
  303. loadGame: function(urlOptions) {
  304. new GameIframe({
  305. "auto_resize":null,
  306. "iframe_url":"`+urlstart+`"+"://game"+active_user.gameId()+".konggames.com"+active_user.gamePath()+'/frame/' + "me-wanna-SuperNova" + '/?kongregate_host=www.kongregate.com',
  307. "alternate_game_file_url":null,
  308. "game_width":`+my_game_width+`,
  309. "game_height":`+my_game_height+`,
  310. "max_game_width":null,
  311. "max_game_height":null,
  312. "game_left":`+my_game_left+`,
  313. "game_top":`+my_game_top+`,
  314. "iframe_class":"dont_hide",
  315. "host":"`+urlstart+`"+"://www.kongregate.com",
  316. "api_host":"`+urlstart+`"+"://api.kongregate.com",
  317. "api_path":"https://chat.kongregate.com/flash/API_AS3_d43c4b859e74432475c1627346078677.swf",
  318. "preview":false,
  319. "game_permalink":active_user.gamePermalink(),
  320. "game_id":active_user.gameId(),
  321. "game_url":"http://www.kongregate.com"+active_user.gamePath(),
  322. "game_version":`+my_game_version+`,
  323. "flash_var_prefix":"kv_",
  324. "post_message":true,
  325. "iframe_host":"`+urlstart+`"+"://game"+active_user.gameId()+".konggames.com",
  326. "game_host":"`+urlstart+`"+"://chat.kongregate.com",
  327. "channel_id":encodeURIComponent(channel_id),
  328. "svid":"`+my_svid+`",
  329. "game_type":"flash"
  330. },
  331. urlOptions, channel_id).createGameIframeElement();
  332.  
  333. }
  334. }
  335.  
  336. function LoadSuperNovaIframe(urlOptions) {
  337. if (!urlOptions) {
  338. urlOptions = '';
  339. }
  340. SuperNovaLoader.loadGame(urlOptions);
  341. document.fire('game:activated');
  342. };
  343.  
  344. RuffleLoader = {
  345. loadGame: function(urlOptions) {
  346. new GameIframe({
  347. "auto_resize":null,
  348. "iframe_url":"`+urlstart+`"+"://game"+active_user.gameId()+".konggames.com"+active_user.gamePath()+'/frame/' + "me-wanna-Ruffle" + '/?kongregate_host=www.kongregate.com',
  349. "alternate_game_file_url":null,
  350. "game_width":`+my_game_width+`,
  351. "game_height":`+my_game_height+`,
  352. "max_game_width":null,
  353. "max_game_height":null,
  354. "game_left":`+my_game_left+`,
  355. "game_top":`+my_game_top+`,
  356. "iframe_class":"dont_hide",
  357. "host":"`+urlstart+`"+"://www.kongregate.com",
  358. "api_host":"`+urlstart+`"+"://api.kongregate.com",
  359. "api_path":"https://chat.kongregate.com/flash/API_AS3_d43c4b859e74432475c1627346078677.swf",
  360. "preview":false,
  361. "game_permalink":active_user.gamePermalink(),
  362. "game_id":active_user.gameId(),
  363. "game_url":"http://www.kongregate.com"+active_user.gamePath(),
  364. "game_version":`+my_game_version+`,
  365. "flash_var_prefix":"kv_",
  366. "post_message":true,
  367. "iframe_host":"`+urlstart+`"+"://game"+active_user.gameId()+".konggames.com",
  368. "game_host":"`+urlstart+`"+"://chat.kongregate.com",
  369. "channel_id":encodeURIComponent(channel_id),
  370. "svid":"`+my_svid+`",
  371. "game_type":"flash"
  372. },
  373. urlOptions, channel_id).createGameIframeElement();
  374.  
  375. }
  376. }
  377.  
  378. function LoadRuffleIframe(urlOptions) {
  379. if (!urlOptions) {
  380. urlOptions = '';
  381. }
  382. RuffleLoader.loadGame(urlOptions);
  383. document.fire('game:activated');
  384. };
  385.  
  386. //]]>`;
  387. document.getElementById("game").appendChild(ic);
  388.  
  389. // Let's make some shiny buttons!
  390. var s=document.createElement("script"), ButtonMaker;
  391. s.type="text/javascript";
  392. s.id="Shiny buttons";
  393. document.head.appendChild(s.appendChild(document.createTextNode('('+function(){
  394. ButtonMaker=function(x){
  395. var ql=document.getElementById("quicklinks");
  396. if(holodeck&&LoadFlashIframe&&ql!==null){
  397. // Flash button
  398. var FlashButton=document.createElement('li');
  399. FlashButton.id="Button to (re)load with Flash";
  400. FlashButton.innerHTML='<a href="#" onclick="LoadFlashIframe(); return false">Flash</a>';
  401. ql.insert(FlashButton,ql.firstChild);
  402. // SuperNova button
  403. var SuperNovaButton=document.createElement('li');
  404. SuperNovaButton.id="Button to (re)load with SuperNova";
  405. SuperNovaButton.innerHTML='<a href="#" onclick="LoadSuperNovaIframe(); return false">SuperNova</a>';
  406. ql.insert(SuperNovaButton,ql.firstChild);
  407. // Ruffle button
  408. var RuffleButton=document.createElement('li');
  409. RuffleButton.id="Button to (re)load with Ruffle";
  410. RuffleButton.innerHTML='<a href="#" onclick="LoadRuffleIframe(); return false">Ruffle</a>';
  411. //ql.insert(RuffleButton,ql.firstChild); //UNHIDE IF THE RUFFLE SCRIPT IS ONE DAY, BY SOME MIRACLE, UPLOADED TO THE KONGREGATE SERVERS.
  412. // No more buttons
  413. setTimeout(function(){delete ButtonMaker;},1);
  414. }
  415. else if(x){setTimeout(function(y){ButtonMaker(y);},10000,x--);}
  416. else{setTimeout(function(){delete ButtonMaker;},1);}
  417. };
  418. ButtonMaker(10);
  419. }+')()')).parentNode);
  420.  
  421. }
  422. };