Twitch Enhancer

aiueo

目前为 2025-02-23 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Twitch Enhancer
  3. // @namespace https://greasyfork.org/ja/users/941284-ぐらんぴ
  4. // @version 2025-02-23
  5. // @description aiueo
  6. // @author ぐらんぴ
  7. // @match https://www.twitch.tv/*
  8. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  9. // @license MIT
  10. // @run-at document-start
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. const origFetch = window.fetch;
  15. window.fetch = async function(url, init) {
  16. let res = await origFetch(url, init);
  17. // Check for null body status codes
  18. if(res.status === 204 || res.status === 205) {
  19. return res; // Return the response as is for these status codes
  20. }
  21. let data;
  22. try{
  23. // Check if the response is not empty before parsing
  24. const text = await res.text();
  25. data = text ? JSON.parse(text) : {};
  26. }catch(err){
  27. console.log('Failed to parse JSON:', err);
  28. return res;
  29. }
  30.  
  31. // console.log(url, data, data.length);
  32. try{
  33. if(url.startsWith('https://edge.ads.twitch.tv/ads')){//Prime Pop-up
  34. data = '';
  35. }
  36. if(url == 'https://gql.twitch.tv/gql#origin=twilight'){// twilight
  37. data.forEach(i =>{
  38. // login
  39. if(i.extensions.operationName == 'CoreActionsCurrentUser'){
  40. i.data.currentUser.roles.isStaff = true
  41. }
  42. if(i.extensions.operationName == 'FrontPageNew_User'){// followedGames
  43. i.data.currentUser.roles.isStaff = true
  44. }
  45. // moderator -- unstable
  46. if(i.extensions.operationName == "PlayerTrackingContextQuery"){
  47. i.data.currentUser.hasTurbo = true
  48. i.data.currentUser.isStaff = true
  49. i.data.user.self.isModerator = true
  50. i.data.user.self.subscriptionBenefit = true
  51. i.data.user.subscriptionProducts[0].hasAdFree = true
  52. i.data.user.subscriptionProducts[1].hasAdFree = true
  53. i.data.user.subscriptionProducts[2].hasAdFree = true
  54. }
  55. if(i.extensions.operationName == 'ChatRestrictions'){
  56. i.data.channel.self.isFirstTimeChatter = true
  57. i.data.channel.self.isModerator = true
  58. i.data.channel.self.isVIP = true
  59. i.data.channel.self.subscriptionBenefit = true
  60. i.data.currentUser.isPhoneNumberVerified = true
  61. }
  62. if(i.extensions.operationName == "CommunityPointsRewardRedemptionContext"){
  63. i.data.community.self.isModerator = true
  64. i.data.community.self.subscriptionBenefit = true
  65. }
  66. if(i.extensions.operationName == 'ChannelPointsContext'){
  67. i.data.community.self.isModerator = true
  68. }
  69. if(i.extensions.operationName == 'Chat_ChannelData'){
  70. i.data.channel.self.isEditor = true
  71. i.data.channel.self.isModerator = true
  72. i.data.channel.self.isVIP = true
  73. }
  74. if(i.extensions.operationName == 'StreamChat'){
  75. i.data.channel.self.isChannelMember = true
  76. i.data.channel.self.isModerator = true
  77. i.data.channel.self.subscriptionBenefit = true
  78. }
  79. if(i.extensions.operationName == 'CurrentUserModeratorStatus'){
  80. i.data.user.self.isModerator = true
  81. }
  82. });
  83. }
  84. }catch(err){
  85. console.log('err modifying data:', err);
  86. }
  87.  
  88. return new Response(JSON.stringify(data), {
  89. headers: res.headers,
  90. status: res.status,
  91. statusText: res.statusText,
  92. });
  93. };
  94.  
  95. const origAppendChild = Element.prototype.appendChild;
  96. Element.prototype.appendChild = function(...args){
  97. try{
  98. if(args[0].className.includes('ScCoreButton-sc-ocjdkq-0')){// Auto Channel Points Claimer
  99. document.querySelectorAll(".claimable-bonus__icon")[0].click()
  100. }
  101. }catch(err){// console.log(err);
  102. }
  103. return origAppendChild.apply(this, args);
  104. };