CCO Pattern Highlighter

Pattern Icons

// ==UserScript==
// @name         CCO Pattern Highlighter
// @namespace    http://tampermonkey.net/
// @version      1.8
// @description  Pattern Icons
// @author       2klex
// @match        *://case-clicker.com/*
// @match        *://*.case-clicker.com/*
// @grant        none
// ==/UserScript==

(function () {
  'use strict';

  const ICONS = {
    "doppler": {
        "sapphire": {
            "url": "https://i.imgur.com/by6BOg9.png",
            "glow": "0 0 12px rgba(0, 153, 255, 0.8)"
        },
        "ruby": {
            "url": "https://i.imgur.com/BbUJ9hD.png",
            "glow": "0 0 12px rgba(255, 0, 64, 0.8)"
        },
        "emerald": {
            "url": "https://i.imgur.com/qBsxDft.png",
            "glow": "0 0 12px rgba(0, 255, 153, 0.8)"
        },
        "blackpearl": {
            "url": "https://i.imgur.com/atZUPhw.png",
            "glow": "0 0 12px rgba(102, 0, 204, 0.8)"
        }
    },
    "fade": {
        "80": {
            "url": "https://i.imgur.com/ZxY4lMl.png",
            "glow": "0 0 12px rgba(255, 102, 204, 0.8)"
        },
        "100": {
            "url": "https://i.imgur.com/SwqnfNP.png",
            "glow": "0 0 12px rgba(255, 255, 102, 0.8)"
        }
    },
    "fireice": {
        "max": {
            "url": "https://i.imgur.com/VkKwObR.png",
            "glow": "0 0 12px rgba(255, 85, 0, 0.8), 0 0 12px rgba(0, 128, 255, 0.8)"
        }
    },
    "casehardened": {
        "bg": {
            "url": "https://i.imgur.com/6pDs0BO.png",
            "glow": "0 0 12px rgba(102, 178, 255, 0.8)"
        },
        "gg": {
            "url": "https://i.imgur.com/9U0L9ka.png",
            "glow": "0 0 12px rgba(255, 204, 0, 0.8)"
        },
        "tier2": {
            "url": "https://i.imgur.com/wufyb2f.png",
            "glow": "0 0 12px rgba(255, 102, 204, 0.8)"
        },
        "tier3": {
            "url": "https://i.imgur.com/gP7aiE2.png",
            "glow": "0 0 12px rgba(255, 140, 0, 0.8)"
        },
        "tier4": {
            "url": "https://i.imgur.com/2WXhwNe.png",
            "glow": "0 0 12px rgba(192, 192, 192, 0.8)"
        }
    },
    "gammadoppler": {
        "t1_diamond": {
            "url": "https://i.imgur.com/Yu0lI1H.png",
            "glow": "0 0 12px rgba(0, 225, 255, 0.8)"
        },
        "t2_diamond": {
            "url": "https://i.imgur.com/Uq0nBTm.png",
            "glow": "0 0 12px rgba(0, 200, 255, 0.8)"
        },
        "t3_diamond": {
            "url": "https://i.imgur.com/tRoELM3.png",
            "glow": "0 0 12px rgba(0, 157, 255, 0.8)"
        }
    },
    "slaughter": {
        "diamond_and_heart": {
            "url": "https://i.imgur.com/AvhbFou.png",
            "glow": "0 0 12px rgba(253, 93, 93, 0.8)"
        },
        "diamond": {
            "url": "https://i.imgur.com/xDi4Xqp.png",
            "glow": "0 0 12px rgba(254, 57, 57, 0.8)"
        }
    },
    "slaugther": {
        "heart": {
            "url": "https://i.imgur.com/uWLnSkS.png",
            "glow": "0 0 12px rgba(255, 0, 0, 0.8)"
        },
        "angel": {
            "url": "https://i.imgur.com/dDZg7Zi.png",
            "glow": "0 0 12px rgba(251, 55, 55, 0.8)"
        },
        "phoenix": {
            "url": "https://i.imgur.com/S9tXZKe.png",
            "glow": "0 0 12px rgba(255, 71, 71, 0.8)"
        },
        "kitty": {
            "url": "https://i.imgur.com/G0SMbFY.png",
            "glow": "0 0 12px rgba(254, 67, 67, 0.8)"
        },
        "zebra": {
            "url": "https://i.imgur.com/sE4tsXM.png",
            "glow": "0 0 12px rgba(255, 82, 82, 0.8)"
        },
        "clean_red": {
            "url": "https://i.imgur.com/QsAdVbt.png",
            "glow": "0 0 12px rgba(254, 67, 67, 0.8)"
        }
    }
};

function getVariantFromFilename(src) {
  const lowered = src.toLowerCase();

  // Skip sticker images entirely
  if (lowered.includes('/stickers/') || lowered.includes('sticker')) {
    return null;
  }

  // Doppler gems (normal)
  if (lowered.includes('doppler')) {
    if (lowered.includes('sapphire')) return { type: 'doppler', key: 'sapphire' };
    if (lowered.includes('ruby')) return { type: 'doppler', key: 'ruby' };
    if (lowered.includes('emerald')) return { type: 'doppler', key: 'emerald' };
    if (lowered.includes('blackpearl') || lowered.includes('black_pearl')) return { type: 'doppler', key: 'blackpearl' };
  }

  // Handle known Doppler knives with _bp/_ruby/_sapphire but without "doppler"
  const dopplerKnives = ['survival', 'paracord', 'nomad', 'skeleton'];
  const baseName = lowered.split('/').pop() || ''; // get just filename
  const knifeMatch = dopplerKnives.find(knife => baseName.startsWith(knife + '_'));

  if (knifeMatch) {
    if (baseName.includes('_bp')) return { type: 'doppler', key: 'blackpearl' };
    if (baseName.includes('_ruby')) return { type: 'doppler', key: 'ruby' };
    if (baseName.includes('_sapphire')) return { type: 'doppler', key: 'sapphire' };
  }

  // Fade %
  if (lowered.match(/[_-]100\.png/)) return { type: 'fade', key: '100' };
  if (lowered.match(/[_-]80\.png/)) return { type: 'fade', key: '80' };

  // Fire & Ice
  if (lowered.includes('_fi_max')) return { type: 'fireice', key: 'max' };

  // Case Hardened
  if (lowered.includes('_ch_bg')) return { type: 'casehardened', key: 'bg' };
  if (lowered.includes('_ch_gg')) return { type: 'casehardened', key: 'gg' };
  if (lowered.includes('_ch_tier2')) return { type: 'casehardened', key: 'tier2' };
  if (lowered.includes('_ch_tier3')) return { type: 'casehardened', key: 'tier3' };
  if (lowered.includes('_ch_tier4')) return { type: 'casehardened', key: 'tier4' };

  // Gamma Doppler (tier diamonds without "gamma" or "doppler" in filename)
  if (lowered.includes('_t1_diamond')) return { type: 'gammadoppler', key: 't1_diamond' };
  if (lowered.includes('_t2_diamond')) return { type: 'gammadoppler', key: 't2_diamond' };
  if (lowered.includes('_t3_diamond')) return { type: 'gammadoppler', key: 't3_diamond' };

  // Slaughter patterns
  if (lowered.includes('slaughter') || lowered.includes('slaugther')) {
    if (lowered.includes('diamond_and_heart')) return { type: 'slaughter', key: 'diamond_and_heart' };
    if (lowered.includes('diamond') && !lowered.includes('and')) return { type: 'slaughter', key: 'diamond' };
  }

  // Slaugther patterns
  if (lowered.includes('slaugther')) {
    if (lowered.includes('clean_red')) return { type: 'slaugther', key: 'clean_red' };
    if (lowered.includes('phoenix')) return { type: 'slaugther', key: 'phoenix' };
    if (lowered.includes('heart')) return { type: 'slaugther', key: 'heart' };
    if (lowered.includes('angel')) return { type: 'slaugther', key: 'angel' };
    if (lowered.includes('kitty')) return { type: 'slaugther', key: 'kitty' };
    if (lowered.includes('zebra')) return { type: 'slaugther', key: 'zebra' };
  }

  return null;
}

function flagSkinImage(img) {
  if (img.dataset.dopplerFlagged) return;
  if (img.closest('.mantine-Modal-root')) return;

  const src = img.src || img.dataset.src || '';
  const variant = getVariantFromFilename(src);
  if (!variant) return;

  const wrapper = img.closest('.mantine-Card-root') || img.parentElement;
  if (!wrapper) return;

  const iconData = ICONS[variant.type][variant.key];
  if (!iconData) return;

  const icon = document.createElement('img');
  icon.src = iconData.url;
  icon.alt = variant.key;
  icon.dataset.highlighterIcon = 'true';
  icon.style.position = 'absolute';
  icon.style.top = '8px';
  icon.style.right = '8px'; // will be adjusted below
  icon.style.width = '32px';
  icon.style.height = '32px';
  icon.style.zIndex = '10';
  icon.style.pointerEvents = 'none';
  icon.style.filter = `drop-shadow(${iconData.glow})`;

  wrapper.style.position = 'relative';
  wrapper.appendChild(icon);

  // initial adjustment for this card
  adjustIconPositionForCard(wrapper);

  img.dataset.dopplerFlagged = 'true';
}

function findStickerImagesInCard(wrapper) {
  // Look for ANY stack in the card that contains sticker images OR event stickers
  const stacks = wrapper.querySelectorAll('.mantine-Stack-root');
  for (const stack of stacks) {
    // Check for regular stickers
    let imgs = stack.querySelectorAll('img[alt^="Sticker"]');
    if (imgs.length > 0) return Array.from(imgs);
    
    // Check for event stickers (in /pictures/events/ path)
    imgs = stack.querySelectorAll('img[src*="/pictures/events/"]');
    if (imgs.length > 0) return Array.from(imgs);
  }
  return [];
}

function adjustIconPositionForCard(wrapper) {
  const icon = wrapper.querySelector('img[data-highlighter-icon="true"]');
  if (!icon) return;

  const stickers = findStickerImagesInCard(wrapper);

  // Base padding on the right when no stickers
  let offset = 8;

  if (stickers.length > 0) {
    const sample = stickers[0];
    // Try to measure the actual width; fall back to 40px
    const rect = sample.getBoundingClientRect();
    const widthAttr = parseInt(sample.getAttribute('width'), 10);
    const styleWidth = parseInt(sample.style.width, 10);

    const stickerWidth =
      (rect && rect.width) ||
      (Number.isFinite(widthAttr) ? widthAttr : 0) ||
      (Number.isFinite(styleWidth) ? styleWidth : 0) ||
      40;

    const gap = 8; // small spacing between sticker column and our icon
    offset += Math.ceil(stickerWidth) + gap;
  }

  icon.style.right = offset + 'px';
}

function adjustAllIconPositions() {
  const cards = document.querySelectorAll('.mantine-Card-root');
  cards.forEach(adjustIconPositionForCard);
}

function scanAllImages() {
  const images = document.querySelectorAll('img:not([data-dopplerFlagged])');
  images.forEach(flagSkinImage);
  // also keep icons positioned correctly if stickers appear later
  adjustAllIconPositions();
}

scanAllImages();

// MutationObserver: rescan & readjust when DOM changes
const observer = new MutationObserver(() => {
  scanAllImages();
  adjustAllIconPositions();
});
observer.observe(document.body, { childList: true, subtree: true });

function handleLoad() {
  setTimeout(() => {
    scanAllImages();
    adjustAllIconPositions();
  }, 1000);
}
window.addEventListener('load', handleLoad);
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址