Chess.com Board Changer, Changes so it has notations! (CORS Fix)

Replace Chess.com's 200.png with custom image *it has notations on it for white and black!*

  1. // ==UserScript==
  2. // @name Chess.com Board Changer, Changes so it has notations! (CORS Fix)
  3. // @namespace http://tampermonkey.net/
  4. // @version v3.193.13.6-7
  5. // @description Replace Chess.com's 200.png with custom image *it has notations on it for white and black!*
  6. // @description Uppercase are for white lowercase Are for black!
  7. // @author NotYou
  8. // @match https://*.chess.com/*
  9. // @grant GM_xmlhttpRequest
  10. // @grant GM_addStyle
  11. // @connect cdn.discordapp.com
  12. // @run-at document-start
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. // Your Discord image URL
  19. const discordImageUrl = 'https://i.imgur.com/zhMb2U4_d.webp?maxwidth=760&fidelity=grand';
  20.  
  21. // We'll use a data URL to avoid CORS issues
  22. // This will be populated once we fetch and convert the image
  23. let dataUrl = '';
  24.  
  25. // Fetch the image and convert it to a data URL to avoid CORS issues
  26. GM_xmlhttpRequest({
  27. method: 'GET',
  28. url: discordImageUrl,
  29. responseType: 'blob',
  30. onload: function(response) {
  31. const blob = response.response;
  32. const reader = new FileReader();
  33. reader.onloadend = function() {
  34. dataUrl = reader.result;
  35. console.log('Image converted to data URL');
  36.  
  37. // Now apply the replacement with our data URL
  38. applyReplacement();
  39. };
  40. reader.readAsDataURL(blob);
  41. },
  42. onerror: function(error) {
  43. console.error('Failed to fetch image:', error);
  44. }
  45. });
  46.  
  47. function applyReplacement() {
  48. // Add CSS to replace all instances of 200.png
  49. GM_addStyle(`
  50. /* Target background images */
  51. [style*="200.png"] {
  52. background-image: url('${dataUrl}') !important;
  53. }
  54.  
  55. /* Target image elements */
  56. img[src*="200.png"] {
  57. content: url('${dataUrl}') !important;
  58. }
  59. `);
  60.  
  61. // Replace existing images
  62. function replaceExistingImages() {
  63. // Skip if data URL is not ready yet
  64. if (!dataUrl) return;
  65.  
  66. // Replace image src attributes
  67. document.querySelectorAll('img[src*="200.png"]').forEach(img => {
  68. img.src = dataUrl;
  69. });
  70.  
  71. // Replace background images
  72. document.querySelectorAll('*').forEach(el => {
  73. const computedStyle = getComputedStyle(el);
  74. if (computedStyle.backgroundImage.includes('200.png')) {
  75. el.style.backgroundImage = `url('${dataUrl}')`;
  76. }
  77. });
  78. }
  79.  
  80. // Run once and then periodically
  81. replaceExistingImages();
  82. setInterval(replaceExistingImages, 2000);
  83.  
  84. // Observe DOM changes
  85. const observer = new MutationObserver(replaceExistingImages);
  86. observer.observe(document.body || document.documentElement, {
  87. childList: true,
  88. subtree: true,
  89. attributes: true,
  90. attributeFilter: ['style', 'src']
  91. });
  92.  
  93. console.log('Chess.com board replacement active with data URL');
  94. }
  95. })();