--------------------------------------------------------------------------------
/CHZZK_Auto_Hide_Annoying_Popups/CHZZK_Auto_Hide_Annoying_Popups.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name CHZZK Auto Hide Annoying Popups
3 | // @namespace CHZZK_Auto_Hide_Annoying_Popups
4 | // @version 0.0.2
5 | // @description Chzzk에서 매일 한 번씩 표시되는 이벤트 알림(첫 충전, 첫 구매, 첫 후원)을 뜨지 않도록 함 + 상단 배너 숨김
6 | // @author Nomo
7 | // @match https://chzzk.naver.com/*
8 | // @homepageURL https://github.com/nomomo/Chzzk_Scripts/CHZZK_Auto_Hide_Annoying_Popups/
9 | // @downloadURL https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Auto_Hide_Annoying_Popups/CHZZK_Auto_Hide_Annoying_Popups.user.js
10 | // @updateURL https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Auto_Hide_Annoying_Popups/CHZZK_Auto_Hide_Annoying_Popups.user.js
11 | // @run-at document-start
12 | // @grant GM_addStyle
13 | // ==/UserScript==
14 |
15 | (function () {
16 | 'use strict';
17 |
18 | // 오늘 날짜 (YYYY-MM-DD)
19 | const today = (() => {
20 | const d = new Date();
21 | const yyyy = d.getFullYear();
22 | const mm = String(d.getMonth() + 1).padStart(2, '0');
23 | const dd = String(d.getDate()).padStart(2, '0');
24 | return `${yyyy}-${mm}-${dd}`;
25 | })();
26 |
27 | // 숨길 팝업/이벤트 관련 키 목록
28 | const HIDE_KEYS = [
29 | 'FIRST_PURCHASE_PROMO_CHEEZE_CHARGE',
30 | 'FIRST_PURCHASE_PROMO_CHEAT_KEY',
31 | 'FIRST_PURCHASE_PROMO_DONATION'
32 | ];
33 |
34 | HIDE_KEYS.forEach(key => {
35 | if (localStorage.getItem(key) !== today) {
36 | localStorage.setItem(key, today);
37 | }
38 | });
39 |
40 | GM_addStyle(`
41 | [class^="band_banner_container__"] {
42 | display: none !important;
43 | }
44 | `);
45 | })();
46 |
--------------------------------------------------------------------------------
/CHZZK_Max_Quality/CHZZK_Max_Quality.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name CHZZK Max Quality
3 | // @namespace CHZZK_Max_Quality
4 | // @version 0.0.1
5 | // @description Forces video quality to 1080p on chzzk.naver.com
6 | // @author Nomo
7 | // @match https://chzzk.naver.com/*
8 | // @supportURL https://github.com/nomomo/Chzzk_Scripts/issues
9 | // @homepage https://github.com/nomomo/Chzzk_Scripts/
10 | // @downloadURL https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Max_Quality/CHZZK_Max_Quality.user.js
11 | // @updateURL https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Max_Quality/CHZZK_Max_Quality.user.js
12 | // @run-at document-start
13 | // @grant none
14 | // ==/UserScript==
15 |
16 | (function() {
17 | 'use strict';
18 | try {
19 | const fixedQuality = {"label":"1080p","width":1920,"height":1080};
20 | const interval_ms = 1000;
21 |
22 | function fixVideoQuality() {
23 | localStorage.setItem('live-player-video-track', JSON.stringify(fixedQuality));
24 | //console.log('Video quality fixed to 1080p');
25 | }
26 |
27 | fixVideoQuality();
28 |
29 | // 무식한 것이 때론 가장 편하다.
30 | setInterval(() => {
31 | const currentValue = localStorage.getItem('live-player-video-track');
32 | if (currentValue !== JSON.stringify(fixedQuality)) {
33 | fixVideoQuality();
34 | }
35 | }, interval_ms);
36 | }
37 | catch(e){
38 | console.log("Failed to set max. quality by CHZZK_Max_Quality.user.js");
39 | }
40 |
41 | // 나중에 트위치처럼 비디오 품질을 지맘대로 낮춘다거나, 더 많은 유저의 귀찮음을 유발하는 케이스가 나오면 그 때 추가 기능 개발을 고려해봅시다.
42 |
43 | })();
--------------------------------------------------------------------------------
/CHZZK_Never_Stop_At_Start/README.md:
--------------------------------------------------------------------------------
1 | # CHZZK Never Stop At Start
2 |
3 | - 특정 확장기능과 충돌하여 라이브 시작 시 플레이어가 일시정지 되는 문제를 고칩니다.
4 |
5 | ## Install
6 |
7 | 설치 방법을 설명합니다.
8 |
9 | ### STEP 1. ScriptManager
10 |
11 | 아래 리스트에서 본인이 사용 중인 브라우저에 맞는 링크에 접속한 후, 유저스크립트 관리 확장기능인 Tampermonkey 를 설치하세요.
12 |
13 | - Chrome - [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)
14 | - Firefox - [Tampermonkey](https://addons.mozilla.org/ko/firefox/addon/tampermonkey/)
15 | - Opera - [Tampermonkey](https://addons.opera.com/extensions/details/tampermonkey-beta/)
16 | - Safari - [Tampermonkey](https://safari.tampermonkey.net/tampermonkey.safariextz)
17 | - Edge - [Tampermonkey](https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd)
18 |
19 | ### STEP 2. UserScript
20 |
21 | - 유저스크립트 관리 확장기능 설치 후 아래의 링크를 클릭하세요. 이후 뜨는 창에서 "설치" 버튼을 눌러 스크립트를 설치합니다.
22 | - [https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Never_Stop_At_Start/CHZZK_Never_Stop_At_Start.user.js](https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Never_Stop_At_Start/CHZZK_Never_Stop_At_Start.user.js)
23 |
24 | 이것으로 설치는 끝입니다. 즐겁게 사용하세요~
25 |
26 | > 주의: 본 스크립트를 설치 및 사용하며 브라우저 과부하로 인한 응답 없음/뻗음으로 인한 데이터 손실이나 기타 발생하는 다른 문제에 대하여 개발자는 책임지지 않음(보고된 문제는 없음)
27 | > 본 스크립트는 Tampermonkey 외의 스크립트 매니저에서는 정상 동작하지 않을 수 있습니다.
28 |
29 | ### 0.0.2 - Apr. 22, 2024
30 |
31 | - Firefox 브라우저에서 동영상을 너무 빨리 다시 시작하면 문제가 간헐적으로 발생해서 동작 방식을 조금 바꿨어요.
32 |
33 | ### 0.0.1 - Apr. 13, 2024
34 |
35 | - 최초 커밋
36 |
37 | ## License
38 |
39 | MIT
40 |
41 | ## Happy??
42 |
43 |
--------------------------------------------------------------------------------
/CHZZK_Hide_Blind_Chat_VOD/README.md:
--------------------------------------------------------------------------------
1 | # CHZZK Hide Blind Chat in VOD
2 |
3 | - Chzzk 다시보기(VOD) 에서 블라인드된 채팅 메시지를 숨겨줘요.
4 |
5 | ## Install
6 |
7 | 설치 방법을 설명합니다.
8 |
9 | ### STEP 1. ScriptManager
10 |
11 | 아래 리스트에서 본인이 사용 중인 브라우저에 맞는 링크에 접속한 후, 유저스크립트 관리 확장기능인 Tampermonkey 를 설치하세요.
12 |
13 | - Chrome - [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)
14 | - Firefox - [Tampermonkey](https://addons.mozilla.org/ko/firefox/addon/tampermonkey/)
15 | - Opera - [Tampermonkey](https://addons.opera.com/extensions/details/tampermonkey-beta/)
16 | - Safari - [Tampermonkey](https://safari.tampermonkey.net/tampermonkey.safariextz)
17 | - Edge - [Tampermonkey](https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd)
18 |
19 | ### STEP 2. UserScript
20 |
21 | - 유저스크립트 관리 확장기능 설치 후 아래의 링크를 클릭하세요. 이후 뜨는 창에서 "설치" 버튼을 눌러 스크립트를 설치합니다.
22 | - [https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Hide_Blind_Chat_VOD/CHZZK_Hide_Blind_Chat_VOD.user.js](https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Hide_Blind_Chat_VOD/CHZZK_Hide_Blind_Chat_VOD.user.js)
23 |
24 | 이것으로 설치는 끝입니다. 즐겁게 사용하세요~
25 |
26 | > 주의: 본 스크립트를 설치 및 사용하며 브라우저 과부하로 인한 응답 없음/뻗음으로 인한 데이터 손실이나 기타 발생하는 다른 문제에 대하여 개발자는 책임지지 않음(보고된 문제는 없음)
27 | > 본 스크립트는 Tampermonkey 외의 스크립트 매니저에서는 정상 동작하지 않을 수 있습니다.
28 |
29 | ## Note
30 |
31 | - 코드의 95% 이상을 ChatGPT로 작성했어요. 예외처리 같은 것이 제대로 안 되어 있긴 한데 현재는 대충 잘 되는 것 같아요. 문제가 생기면 스크립트를 비활성화 하세요.
32 |
33 | ### 0.0.2 - Sep. 29, 2024
34 |
35 | - CSS를 이용하여 구현하도록 변경
36 |
37 | ### 0.0.1 - Sep. 29, 2024
38 |
39 | - 최초 커밋
40 |
41 | ## License
42 |
43 | MIT
44 |
45 | ## Happy??
46 |
47 |
48 |
--------------------------------------------------------------------------------
/CHZZK_Auto_Hide_Annoying_Popups/README.md:
--------------------------------------------------------------------------------
1 | # CHZZK Auto Hide Annoying Popups
2 |
3 | * Chzzk에서 매일 한 번씩 표시되는 🐕짜증나는 이벤트 알림(첫 충전, 첫 구매, 첫 후원)을 뜨지 않도록 함
4 | * 시크릿 모드(Incognito mode) 에서는 정상 동작하지 않을 수 있습니다.
5 |
6 | 
7 |
8 | ## Install
9 |
10 | 설치 방법을 설명합니다.
11 |
12 | ### STEP 1. ScriptManager
13 |
14 | 아래 리스트에서 본인이 사용 중인 브라우저에 맞는 링크에 접속한 후, 유저스크립트 관리 확장기능인 Tampermonkey를 설치하세요.
15 |
16 | * Chrome - [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)
17 | * Firefox - [Tampermonkey](https://addons.mozilla.org/ko/firefox/addon/tampermonkey/)
18 | * Opera - [Tampermonkey](https://addons.opera.com/extensions/details/tampermonkey-beta/)
19 | * Safari - [Tampermonkey](https://safari.tampermonkey.net/tampermonkey.safariextz)
20 | * Edge - [Tampermonkey](https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd)
21 |
22 | ### STEP 2. UserScript
23 |
24 | * 유저스크립트 관리 확장기능 설치 후 아래의 링크를 클릭하세요.
25 | 이후 뜨는 창에서 "설치" 버튼을 눌러 스크립트를 설치합니다.
26 |
27 | * [https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Auto_Hide_Annoying_Popups/CHZZK_Auto_Hide_Annoying_Popups.user.js](https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Auto_Hide_Annoying_Popups/CHZZK_Auto_Hide_Annoying_Popups.user.js)
28 |
29 | 이것으로 설치는 끝입니다. 즐겁게 사용하세요~
30 |
31 | > **주의:** 본 스크립트를 설치 및 사용하며 브라우저 과부하, 응답 없음, 데이터 손실이나 기타 문제 발생 시 개발자는 책임지지 않습니다.
32 | > 본 스크립트는 Tampermonkey 외의 스크립트 매니저에서는 정상 동작하지 않을 수 있습니다.
33 |
34 | ### 0.0.2 - Nov. 2, 2025
35 |
36 | * "일부 크롬 브라우저의 라이브 재생 불가 현상 및 해결 방법 안내"를 숨김
37 |
38 | ### 0.0.1 - Aug. 9, 2025
39 |
40 | * 최초 커밋
41 |
42 | ## License
43 |
44 | MIT
45 |
46 | ## Happy??
47 |
48 |
--------------------------------------------------------------------------------
/CHZZK_Max_Quality/README.md:
--------------------------------------------------------------------------------
1 | # CHZZK Max Quality
2 |
3 | > 치지직 보다보면 간혹 가다 720p 방송(최대화질이 1080p가 아닌)이 있는데 그 방송을 보다가 다른 방송을 가면 전 방송에서의 최대화질로(720p)로 설정되서 매번 방송을 돌릴때마다 화질 설정 하는 게 귀찮습니다. 혹시 기능 추가가 가능할까요?
4 |
5 | - 라는 요청에 의해 만든 스크립트 입니다.
6 | - 이전에 시청하던 비디오 품질이 1080p 가 아니더라도, 새롭게 시청할 비디오의 최대 품질이 1080p 인 경우 1080p로 재생을 시작하도록 합니다.
7 | - 브라우저가 시크릿 모드(Incognito Mode)인 경우 제대로 동작하지 않을 수 있습니다.
8 |
9 | ## Install
10 |
11 | 설치 방법을 설명합니다.
12 |
13 | ### STEP 1. ScriptManager
14 |
15 | 아래 리스트에서 본인이 사용 중인 브라우저에 맞는 링크에 접속한 후, 유저스크립트 관리 확장기능인 Tampermonkey 를 설치하세요.
16 |
17 | - Chrome - [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)
18 | - Firefox - [Tampermonkey](https://addons.mozilla.org/ko/firefox/addon/tampermonkey/)
19 | - Opera - [Tampermonkey](https://addons.opera.com/extensions/details/tampermonkey-beta/)
20 | - Safari - [Tampermonkey](https://safari.tampermonkey.net/tampermonkey.safariextz)
21 | - Edge - [Tampermonkey](https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd)
22 |
23 | ### STEP 2. UserScript
24 |
25 | - 유저스크립트 관리 확장기능 설치 후 아래의 링크를 클릭하세요. 이후 뜨는 창에서 "설치" 버튼을 눌러 스크립트를 설치합니다.
26 | - [https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Max_Quality/CHZZK_Max_Quality.user.js](https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Max_Quality/CHZZK_Max_Quality.user.js)
27 |
28 | 이것으로 설치는 끝입니다. 즐겁게 사용하세요~
29 |
30 | > 주의: 본 스크립트를 설치 및 사용하며 브라우저 과부하로 인한 응답 없음/뻗음으로 인한 데이터 손실이나 기타 발생하는 다른 문제에 대하여 개발자는 책임지지 않음(보고된 문제는 없음)
31 | > 본 스크립트는 Tampermonkey 외의 스크립트 매니저에서는 정상 동작하지 않을 수 있습니다.
32 |
33 | ### 0.0.1 - Sep. 11, 2024
34 |
35 | - 최초 커밋
36 |
37 | ## License
38 |
39 | MIT
40 |
41 | ## Happy??
42 |
43 |
--------------------------------------------------------------------------------
/CHZZK_Degul_Interpreter/README.md:
--------------------------------------------------------------------------------
1 | # CHZZK 데굴어 통역기
2 |
3 | * **데굴**어를 통역합니다.
4 | * 채팅 입력창은 건드리지 않습니다.
5 |
6 |
7 |
8 | ## Install
9 |
10 | ### STEP 1. ScriptManager
11 |
12 | 브라우저에 맞는 링크에서 Tampermonkey를 설치하세요.
13 |
14 | * Chrome - [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)
15 | * Firefox - [Tampermonkey](https://addons.mozilla.org/ko/firefox/addon/tampermonkey/)
16 | * Opera - [Tampermonkey](https://addons.opera.com/extensions/details/tampermonkey-beta/)
17 | * Safari - [Tampermonkey](https://safari.tampermonkey.net/tampermonkey.safariextz)
18 | * Edge - [Tampermonkey](https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd)
19 |
20 | ### STEP 2. UserScript
21 |
22 | 아래 링크를 클릭한 뒤, 뜨는 창에서 **설치** 버튼을 눌러 스크립트를 설치합니다.
23 |
24 | * [https://github.com/nomomo/Chzzk\_Scripts/raw/main/CHZZK\_Degul\_Interpreter/CHZZK\_Degul\_Interpreter.user.js](https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Degul_Interpreter/CHZZK_Degul_Interpreter.user.js)
25 |
26 | 설치는 여기까지입니다. 즐겁게 사용하세요!
27 |
28 | ## WARNING
29 | - 2025년 8월 16일 기준으로 채팅에서 문제는 없었으나, 치지직 레이아웃 업데이트 등에 따라 번역된 내용이 그대로 전송될 수 있습니다. **번역된 내용이 채팅/댓글로 입력되어 발생하는 사고에 대해서 개발자는 책임지지 않습니다.**
30 |
31 | ## Note
32 |
33 | - 코드의 90% 이상을 ChatGPT로 작성했어요. 성능 이슈가 있을 수도 있는데 대충 잘 되는 것 같아요. 문제가 생기면 스크립트를 비활성화 하세요.
34 | - 본 스크립트 사용 중 발생하는 브라우저 과부하, 응답 없음, 데이터 손실 등 문제에 대해 개발자는 책임지지 않습니다.
35 | - Tampermonkey 외 스크립트 매니저에서는 정상 동작하지 않을 수 있습니다.
36 |
37 | ## Changelog
38 |
39 | ### 0.0.2 — Aug. 16, 2025
40 |
41 | * 통역 대상 단어 업데이트
42 |
43 | ### 0.0.1 — Aug. 16, 2025
44 |
45 | * 첫 커밋
46 |
47 | ## License
48 |
49 | MIT
50 |
51 | ## Support
52 |
53 |
--------------------------------------------------------------------------------
/Better_Multichzzk/README.md:
--------------------------------------------------------------------------------
1 | # Better_Multichzzk
2 |
3 | mul.live에서 자동으로 아래의 것들을 해줍니다.
4 |
5 | - 자동으로 화면 넓게
6 | - 채팅창 숨기기
7 | - 모두 음소거
8 |
9 | ## Install
10 |
11 | 설치 방법을 설명합니다.
12 |
13 | ### STEP 1. ScriptManager
14 |
15 | 아래 리스트에서 본인이 사용 중인 브라우저에 맞는 링크에 접속한 후, 유저스크립트 관리 확장기능인 Tampermonkey 를 설치하세요.
16 |
17 | - Chrome - [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)
18 | - Firefox - [Tampermonkey](https://addons.mozilla.org/ko/firefox/addon/tampermonkey/)
19 | - Opera - [Tampermonkey](https://addons.opera.com/extensions/details/tampermonkey-beta/)
20 | - Safari - [Tampermonkey](https://safari.tampermonkey.net/tampermonkey.safariextz)
21 | - Edge - [Tampermonkey](https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd)
22 |
23 | ### STEP 2. UserScript
24 |
25 | - 유저스크립트 관리 확장기능 설치 후 아래의 링크를 클릭하세요. 이후 뜨는 창에서 "설치" 버튼을 눌러 스크립트를 설치합니다.
26 | - [https://github.com/nomomo/Chzzk_Scripts/raw/main/Better_Multichzzk/Better_Multichzzk.user.js](https://github.com/nomomo/Chzzk_Scripts/raw/main/Better_Multichzzk/Better_Multichzzk.user.js)
27 |
28 | 이것으로 설치는 끝입니다. 즐겁게 사용하세요~
29 |
30 | > 주의: 본 스크립트를 설치 및 사용하며 브라우저 과부하로 인한 응답 없음/뻗음으로 인한 데이터 손실이나 기타 발생하는 다른 문제에 대하여 개발자는 책임지지 않음(보고된 문제는 없음)
31 | > 본 스크립트는 Tampermonkey 외의 스크립트 매니저에서는 정상 동작하지 않을 수 있습니다.
32 |
33 | ### 0.0.5 - Feb. 18, 2024
34 |
35 | - mul.live 도메인 추가
36 |
37 | ### 0.0.4 - Dec. 23, 2023
38 |
39 | - 음소거 기능 누락 문제 수정
40 |
41 | ### 0.0.3 - Dec. 23, 2023
42 |
43 | - 치지직과 트위치를 같이 멀티스트림으로 시청하는 경우 트위치 재생이 올바르게 되지 않는 문제 수정
44 |
45 | ### 0.0.2 - Dec. 23, 2023
46 |
47 | - 치즈나이프 확장 프로그램과 충돌하여 치지직 플레이어가 자동으로 PIP 모드가 되는 버그 수정
48 |
49 | ### 0.0.1 - Dec. 23, 2023
50 |
51 | - 최초 커밋
52 |
53 | ## License
54 |
55 | MIT
56 |
57 | ## Happy??
58 |
59 |
--------------------------------------------------------------------------------
/CHZZK_Restore_Blind_Chat/README.md:
--------------------------------------------------------------------------------
1 | # CHZZK Restore Blind Chat
2 |
3 | - 이 스크립트는 Chzzk에서 관리자가 블라인드한 채팅 메시지를 표시합니다.
4 | - 메시지가 숨겨지면 "[블라인드된 메시지]"라는 접두어와 함께 원래 메시지를 표시합니다.
5 |
6 | ## 설치
7 |
8 | 아래 단계를 따라 UserScript를 설치하세요.
9 |
10 | ### STEP 1. ScriptManager
11 |
12 | 먼저 아래 링크에서 본인이 사용 중인 브라우저에 맞는 Tampermonkey 확장 프로그램을 설치하세요.
13 |
14 | - Chrome - [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)
15 | - Firefox - [Tampermonkey](https://addons.mozilla.org/ko/firefox/addon/tampermonkey/)
16 | - Opera - [Tampermonkey](https://addons.opera.com/extensions/details/tampermonkey-beta/)
17 | - Safari - [Tampermonkey](https://safari.tampermonkey.net/tampermonkey.safariextz)
18 | - Edge - [Tampermonkey](https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd)
19 |
20 | ### STEP 2. UserScript
21 |
22 | Tampermonkey 확장 프로그램 설치 후, 아래 링크를 클릭하세요. 팝업 창에서 "설치" 버튼을 눌러 스크립트를 설치합니다.
23 |
24 | - [https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Restore_Blind_Chat/CHZZK_Restore_Blind_Chat.user.js](https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Restore_Blind_Chat/CHZZK_Restore_Blind_Chat.user.js)
25 |
26 | 설치는 여기까지입니다. 즐겁게 사용하세요~
27 |
28 | > 주의: 본 스크립트를 설치 및 사용하며 발생하는 브라우저 과부하로 인한 응답 없음, 뻗음으로 인한 데이터 손실이나 기타 문제에 대해 개발자는 책임지지 않습니다(보고된 문제는 없음).
29 | > 본 스크립트는 Tampermonkey 외의 스크립트 매니저에서는 정상 동작하지 않을 수 있습니다.
30 |
31 | ## 참고사항
32 |
33 | - 코드의 95% 이상을 ChatGPT로 작성했습니다. 예외 처리가 제대로 되어 있지는 않지만 현재는 대체로 잘 동작합니다. 문제가 생기면 스크립트를 비활성화하세요.
34 |
35 | ### 0.0.3 - Mar 26, 2025
36 |
37 | - 치지직 레이아웃 업데이트 후 동작하지 않는 문제 수정 (wisenb님 감사해요!)
38 |
39 | ### 0.0.2 - Sep 29, 2024
40 |
41 | - 메시지가 블라인드 될 때 간헐적으로 자동 스크롤이 멈추는 문제 수정
42 |
43 | ### 0.0.1 - Jul 14, 2024
44 |
45 | - 최초 커밋
46 |
47 | ## 라이선스
48 |
49 | MIT
50 |
51 | ## 후원하기
52 |
53 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # chzzk_scripts
2 |
3 | 개인적인 용도로 사용하려고 만든 chzzk user-scripts 모음집
4 |
5 | - [Better Multichzzk](https://github.com/nomomo/Chzzk_Scripts/tree/main/Better_Multichzzk): 멀티치지직에서 자동으로 화면 넓게
6 | - [CHZZK sign in iframe](https://github.com/nomomo/Chzzk_Scripts/tree/main/CHZZK_sign_in_iframe): Embed(Iframe)으로 삽입된 곳에서도 로그인 유지
7 | - [CHZZK Live Progress Slider](https://github.com/nomomo/Chzzk_Scripts/tree/main/CHZZK_Live_Progress_Slider): 라이브 스트림 플레이어에 Progress Slider 를 표시
8 | - [CHZZK Always Awake](https://github.com/nomomo/Chzzk_Scripts/tree/main/CHZZK_Always_Awake): 탭이 비활성되어도 비활성 아닌척 함
9 | - [CHZZK Never Stop At Start](https://github.com/nomomo/Chzzk_Scripts/tree/main/CHZZK_Never_Stop_At_Start): 특정 확장기능이 라이브를 일시정지 시키는 문제를 고침
10 | - [CHZZK Favorite Streamer](https://github.com/nomomo/Chzzk_Scripts/tree/main/CHZZK_Favorite_Streamer): 즐겨찾는 팔로우 스트리머 설정
11 | - [CHZZK Restore Blind Chat](https://github.com/nomomo/Chzzk_Scripts/tree/main/CHZZK_Restore_Blind_Chat): 블라인드된 메시지 표시
12 | - [CHZZK User Memo](https://github.com/nomomo/Chzzk_Scripts/tree/main/CHZZK_User_Memo): 채팅창에 유저 메모 기능을 추가 (Alpha test version)
13 | - [CHZZK Max Quality](https://github.com/nomomo/Chzzk_Scripts/tree/main/CHZZK_Max_Quality): 최고 품질로 스트림 재생 시작
14 | - [CHZZK Hide Blind Chat VOD](https://github.com/nomomo/Chzzk_Scripts/tree/main/CHZZK_Hide_Blind_Chat_VOD): 치지직 다시보기(VOD) 에서 블라인드된 채팅 메시지를 숨김
15 | - [CHZZK Video RealTime](https://github.com/nomomo/Chzzk_Scripts/tree/main/CHZZK_Video_RealTime): 치지직 다시보기 비디오의 슬라이더 바에 마우스를 올렸을 때, 비디오의 실제 시간을 표시
16 | - [CHZZK Auto Hide Annoying Popups](https://github.com/nomomo/Chzzk_Scripts/tree/main/CHZZK_Auto_Hide_Annoying_Popups): 매일 한 번씩 표시되는 이벤트 알림(첫 충전, 첫 구매, 첫 후원)을 뜨지 않도록 함
17 | - [CHZZK 데굴어 통역기](https://github.com/nomomo/Chzzk_Scripts/tree/main/CHZZK_Degul_Interpreter): 데굴어를 통역
18 |
19 | ## 🪦 Deprecated Scripts
20 |
21 | 더 이상 사용하지 않거나 유지보수가 중단된 스크립트입니다.
22 |
23 | - ~~[CHZZK Better Shorts Player](https://github.com/nomomo/Chzzk_Scripts/tree/main/CHZZK_Better_Shorts_Player): 클립 보기 화면에 볼륨 컨트롤러 추가, 동작 개선~~
24 |
25 | ## License
26 |
27 | MIT
28 |
--------------------------------------------------------------------------------
/CHZZK_Better_Shorts_Player/README.md:
--------------------------------------------------------------------------------
1 | # CHZZK Better Shorts Player
2 |
3 | > ⚠️ **Deprecated**
4 | > 이 스크립트는 더 이상 유지보수되지 않으며, 설치를 권장하지 않습니다.
5 | > 클립 페이지에 볼륨 컨트롤러 기능이 **네이티브로 추가**되어 더 이상 필요하지 않게 되었습니다.
6 |
7 | - Chzzk의 클립 페이지에 볼륨 컨트롤러를 추가해줘요.
8 | - 이전에 설정한 볼륨을 기억해요.
9 | - 플레이어에 마우스를 올린 상태에서만 오버레이(제목, 재생바, 컨트롤 버튼 등)를 표시해요.
10 |
11 | ## Preview
12 |
13 | https://github.com/user-attachments/assets/83aabceb-e2e9-4cc4-bc9a-91d3568e82e9
14 |
15 | ## Install
16 |
17 | 설치 방법을 설명합니다.
18 |
19 | ### STEP 1. ScriptManager
20 |
21 | 아래 리스트에서 본인이 사용 중인 브라우저에 맞는 링크에 접속한 후, 유저스크립트 관리 확장기능인 Tampermonkey 를 설치하세요.
22 |
23 | - Chrome - [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)
24 | - Firefox - [Tampermonkey](https://addons.mozilla.org/ko/firefox/addon/tampermonkey/)
25 | - Opera - [Tampermonkey](https://addons.opera.com/extensions/details/tampermonkey-beta/)
26 | - Safari - [Tampermonkey](https://safari.tampermonkey.net/tampermonkey.safariextz)
27 | - Edge - [Tampermonkey](https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd)
28 |
29 | ### STEP 2. UserScript
30 |
31 | - 유저스크립트 관리 확장기능 설치 후 아래의 링크를 클릭하세요. 이후 뜨는 창에서 "설치" 버튼을 눌러 스크립트를 설치합니다.
32 | - [https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Better_Shorts_Player/CHZZK_Better_Shorts_Player.user.js](https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Better_Shorts_Player/CHZZK_Better_Shorts_Player.user.js)
33 |
34 | 이것으로 설치는 끝입니다. 즐겁게 사용하세요~
35 |
36 | > 주의: 본 스크립트를 설치 및 사용하며 브라우저 과부하로 인한 응답 없음/뻗음으로 인한 데이터 손실이나 기타 발생하는 다른 문제에 대하여 개발자는 책임지지 않음(보고된 문제는 없음)
37 | > 본 스크립트는 Tampermonkey 외의 스크립트 매니저에서는 정상 동작하지 않을 수 있습니다.
38 |
39 | ## Note
40 |
41 | - 코드의 95% 이상을 ChatGPT로 작성했어요. 예외처리 같은 것이 제대로 안 되어 있긴 한데 현재는 대충 잘 되는 것 같아요. 문제가 생기면 스크립트를 비활성화 하세요.
42 |
43 | ### 0.0.1 - Aug. 16, 2024
44 |
45 | - 최초 커밋
46 |
47 | ## License
48 |
49 | MIT
50 |
51 | ## Happy??
52 |
53 |
54 |
--------------------------------------------------------------------------------
/CHZZK_Video_RealTime/README.md:
--------------------------------------------------------------------------------
1 | # CHZZK Video RealTime
2 |
3 | - 이 스크립트는 CHZZK 다시보기 비디오의 슬라이더 바에 마우스를 올렸을 때, 비디오의 실제 시간을 표시해줍니다.
4 | - 동작 원리: 서버에서 가져온 다시보기의 라이브 시작 시간에 현재 마우스가 가리키는 시점의 동영상 시간을 더하여 계산된 시간을 표시합니다.
5 |
6 | ## Preview
7 |
8 |
9 |
10 | ## 설치
11 |
12 | 아래 단계를 따라 UserScript를 설치하세요.
13 |
14 | ### STEP 1. ScriptManager
15 |
16 | 먼저 아래 링크에서 본인이 사용 중인 브라우저에 맞는 Tampermonkey 확장 프로그램을 설치하세요.
17 |
18 | - Chrome - [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)
19 | - Firefox - [Tampermonkey](https://addons.mozilla.org/ko/firefox/addon/tampermonkey/)
20 | - Opera - [Tampermonkey](https://addons.opera.com/extensions/details/tampermonkey-beta/)
21 | - Safari - [Tampermonkey](https://safari.tampermonkey.net/tampermonkey.safariextz)
22 | - Edge - [Tampermonkey](https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd)
23 |
24 | ### STEP 2. UserScript
25 |
26 | Tampermonkey 확장 프로그램 설치 후, 아래 링크를 클릭하세요. 팝업 창에서 "설치" 버튼을 눌러 스크립트를 설치합니다.
27 |
28 | - [https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Video_RealTime/CHZZK_Video_RealTime.user.js](https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Video_RealTime/CHZZK_Video_RealTime.user.js)
29 |
30 | 설치는 여기까지입니다. 즐겁게 사용하세요~
31 |
32 | > 주의: 본 스크립트를 설치 및 사용하며 발생하는 브라우저 과부하로 인한 응답 없음, 뻗음으로 인한 데이터 손실이나 기타 문제에 대해 개발자는 책임지지 않습니다(보고된 문제는 없음).
33 | > 본 스크립트는 Tampermonkey 외의 스크립트 매니저에서는 정상 동작하지 않을 수 있습니다.
34 |
35 | ## 참고사항
36 |
37 | - 다시보기 비디오에 싱크 문제가 있거나 서버에서 가져오는 라이브 시작 시간에 문제가 있는 경우 표시되는 시간이 실제 시간과 다를 수 있으므로 참고 용으로만 사용하세요.
38 | - 라이브 시간이 길어 다시보기가 자동으로 잘린 경우 해당 라이브의 모든 다시보기는 동일한 라이브 시작 시간을 가집니다. 스크립트는 이전 다시보기의 정보를 체크하여 현재 보고있는 다시보기가 이전 다시보기에서 이어지는 것인지를 판단하고, 이를 고려하여 실제 시간을 계산합니다.
39 | - 만약 일부 다시보기가 숨겨진 경우 실제 시간이 잘못 계산될 수 있습니다.
40 | - 코드의 90% 이상을 ChatGPT로 작성했습니다. 비효율적인 부분이 있고 예외 처리가 제대로 되어 있지는 않지만 현재는 대체로 잘 동작합니다. 문제가 생기면 스크립트를 비활성화하세요.
41 |
42 | ### 0.0.1 - Jan 13, 2025
43 |
44 | - 최초 커밋
45 |
46 | ## 라이선스
47 |
48 | MIT
49 |
50 | ## 후원하기
51 |
52 |
--------------------------------------------------------------------------------
/CHZZK_Live_Progress_Slider/README.md:
--------------------------------------------------------------------------------
1 | # CHZZK Live Progress Slider
2 |
3 | - Chzzk에서 라이브 스트림에 Progress Slider 를 표시합니다.
4 | - "실시간" 을 누르면 빨리감기 합니다.
5 | - 로드된 비디오 버퍼 범위에서 탐색할 수 있습니다.
6 |
7 |
8 |
9 | ## Install
10 |
11 | 설치 방법을 설명합니다.
12 |
13 | ### STEP 1. ScriptManager
14 |
15 | 아래 리스트에서 본인이 사용 중인 브라우저에 맞는 링크에 접속한 후, 유저스크립트 관리 확장기능인 Tampermonkey 를 설치하세요.
16 |
17 | - Chrome - [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)
18 | - Firefox - [Tampermonkey](https://addons.mozilla.org/ko/firefox/addon/tampermonkey/)
19 | - Opera - [Tampermonkey](https://addons.opera.com/extensions/details/tampermonkey-beta/)
20 | - Safari - [Tampermonkey](https://safari.tampermonkey.net/tampermonkey.safariextz)
21 | - Edge - [Tampermonkey](https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd)
22 |
23 | ### STEP 2. UserScript
24 |
25 | - 유저스크립트 관리 확장기능 설치 후 아래의 링크를 클릭하세요. 이후 뜨는 창에서 "설치" 버튼을 눌러 스크립트를 설치합니다.
26 | - [https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Live_Progress_Slider/CHZZK_Live_Progress_Slider.user.js](https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Live_Progress_Slider/CHZZK_Live_Progress_Slider.user.js)
27 |
28 | 이것으로 설치는 끝입니다. 즐겁게 사용하세요~
29 |
30 | > 주의: 본 스크립트를 설치 및 사용하며 브라우저 과부하로 인한 응답 없음/뻗음으로 인한 데이터 손실이나 기타 발생하는 다른 문제에 대하여 개발자는 책임지지 않음(보고된 문제는 없음)
31 | > 본 스크립트는 Tampermonkey 외의 스크립트 매니저에서는 정상 동작하지 않을 수 있습니다.
32 |
33 | ## Note
34 |
35 | - 기존 Player의 UI를 활용하므로 탐색 시 Console 창에 "Unhandled promise rejection Error"이 발생했다고 출력되지만 실제 동작에 영향을 주지는 않습니다.
36 |
37 | ### 0.0.4 - Mar. 30, 2025
38 |
39 | - 치지직 UI 업데이트 후 동작하지 않는 문제 수정
40 | - 타임머신이 활성화 되지 않는 경우에만 동작하도록 수정
41 |
42 | ### 0.0.3 - Dec. 20, 2024
43 |
44 | - 치지직 UI 업데이트 후 동작하지 않는 문제 수정
45 |
46 | ### 0.0.2 - Aug. 1, 2024
47 |
48 | - 치지직 UI 업데이트 후 동작하지 않는 문제 수정
49 |
50 | ### 0.0.1 - Feb. 18, 2024
51 |
52 | - 최초 커밋
53 |
54 | ## License
55 |
56 | MIT
57 |
58 | ## Happy??
59 |
60 |
--------------------------------------------------------------------------------
/CHZZK_Favorite_Streamer/README.md:
--------------------------------------------------------------------------------
1 | # CHZZK Favorite Streamer
2 |
3 | - Chzzk의 팔로우 메뉴에서 즐겨찾는 스트리머를 설정할 수 있습니다.
4 | - 즐겨찾기에 추가된 스트리머는 팔로우 메뉴의 맨 위에 표시됩니다.
5 | - 즐겨찾기 설정 메뉴 또는 드래그 앤 드롭으로 순서를 변경할 수 있습니다.
6 |
7 | ## Preview
8 |
9 | https://github.com/nomomo/Chzzk_Scripts/assets/863079/0c12f628-0df4-48e0-876d-a75417d04c36
10 |
11 | ## Install
12 |
13 | 설치 방법을 설명합니다.
14 |
15 | ### STEP 1. ScriptManager
16 |
17 | 아래 리스트에서 본인이 사용 중인 브라우저에 맞는 링크에 접속한 후, 유저스크립트 관리 확장기능인 Tampermonkey 를 설치하세요.
18 |
19 | - Chrome - [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)
20 | - Firefox - [Tampermonkey](https://addons.mozilla.org/ko/firefox/addon/tampermonkey/)
21 | - Opera - [Tampermonkey](https://addons.opera.com/extensions/details/tampermonkey-beta/)
22 | - Safari - [Tampermonkey](https://safari.tampermonkey.net/tampermonkey.safariextz)
23 | - Edge - [Tampermonkey](https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd)
24 |
25 | ### STEP 2. UserScript
26 |
27 | - 유저스크립트 관리 확장기능 설치 후 아래의 링크를 클릭하세요. 이후 뜨는 창에서 "설치" 버튼을 눌러 스크립트를 설치합니다.
28 | - [https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Favorite_Streamer/CHZZK_Favorite_Streamer.user.js](https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Favorite_Streamer/CHZZK_Favorite_Streamer.user.js)
29 |
30 | 이것으로 설치는 끝입니다. 즐겁게 사용하세요~
31 |
32 | > 주의: 본 스크립트를 설치 및 사용하며 브라우저 과부하로 인한 응답 없음/뻗음으로 인한 데이터 손실이나 기타 발생하는 다른 문제에 대하여 개발자는 책임지지 않음(보고된 문제는 없음)
33 | > 본 스크립트는 Tampermonkey 외의 스크립트 매니저에서는 정상 동작하지 않을 수 있습니다.
34 |
35 | ## Note
36 |
37 | - 코드의 95% 이상을 ChatGPT로 작성했어요. 예외처리 같은 것이 제대로 안 되어 있긴 한데 현재는 대충 잘 되는 것 같아요. 문제가 생기면 스크립트를 비활성화 하세요.
38 | - 팔로우 하지 않은 스트리머에 대해서는 즐겨찾기 기능이 제대로 동작하지 않을 수 있어요.
39 |
40 | ### 0.0.4 - July 25, 2025
41 |
42 | - 치지직 레이아웃 업데이트 후 live 화면에서 "★" 및 설정 버튼이 제대로 표시되지 않는 문제 수정
43 |
44 | ### 0.0.3 - May 17, 2025
45 |
46 | - 치지직 레이아웃 업데이트 후 live 화면에서 "★" 버튼이 제대로 표시되지 않는 문제 수정
47 | - 팔로잉 화면에서 드래그로 리스트 순서 변경 시 드래그를 종료하는 시점에 마우스 포인터가 범위 밖에 존재하는 경우 순서 변경을 취소하도록 수정
48 | - 팔로잉 화면에서 섬네일 또는 라이브 제목을 드래그하여 주소창에 옮겨다 두었을 때 해당 페이지에 대한 새 창이 뜨도록 수정
49 |
50 | ### 0.0.2 - Aug. 1, 2024
51 |
52 | - 치지직 UI 업데이트 후 팔로잉 메뉴의 "★" 버튼과 "★설정" 버튼이 보이지 않는 문제 수정
53 |
54 | ### 0.0.1 - Jun. 7, 2024
55 |
56 | - 최초 커밋
57 |
58 | ## License
59 |
60 | MIT
61 |
62 | ## Happy??
63 |
64 |
65 |
--------------------------------------------------------------------------------
/CHZZK_sign_in_iframe/README.md:
--------------------------------------------------------------------------------
1 | # CHZZK_sign_in_iframe
2 |
3 | - 본 스크립트는 iframe(embed)로 삽입된 CHZZK 페이지에서 로그인이 유지되도록 해줍니다.
4 | - 로그인이 유지되므로 iframe(embed)로 삽입된 CHZZK 페이지에서 연령 인증 스트림 시청, 채팅이 가능합니다.
5 | - 로그인은 [chzzk.naver.com](https://chzzk.naver.com) 에서 직접해야 합니다.
6 | - **본 스크립트는 Chrome 계열 브라우저의 경우 Tampermonkey Beta 버전에서만 동작합니다. (스크립트 매니저가 GM_cookie 기능을 지원해야 함)**
7 |
8 | ## 설치 방법
9 |
10 | ### STEP 1. Script Manager 설치
11 |
12 | **Chrome 계열 브라우저의 경우 Tampermonkey Beta 버전에서만 작동합니다.** 아래 링크에서 Tampermonkey Beta 를 설치하세요.
13 |
14 | 기존 Tampermonkey 사용자도 Tampermonkey Beta 버전을 추가로 설치해야 합니다.
15 |
16 | - Chrome - [Tampermonkey Beta](https://chromewebstore.google.com/detail/tampermonkey-beta/gcalenpjmijncebpfijmoaglllgpjagf)
17 |
18 | ### STEP 2. 개발자 모드 활성화
19 |
20 | - 2024년 5월부터 Tampermonkey를 사용하려면 개발자 모드를 활성화 해야합니다.
21 | - **chrome://extensions** 로 접속한 후, 확장 프로그램 관리 페이지 우측 상단의 "개발자 모드"를 켜세요.
22 |
23 | ### STEP 3. UserScript 설치
24 |
25 | - 유저스크립트 관리 확장기능 설치 후 아래의 링크를 클릭하세요. 이후 뜨는 창에서 "설치" 버튼을 눌러 스크립트를 설치합니다.
26 | - [https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_sign_in_iframe/CHZZK_sign_in_iframe.user.js](https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_sign_in_iframe/CHZZK_sign_in_iframe.user.js)
27 |
28 | 이것으로 설치는 끝입니다. 즐겁게 사용하세요~
29 |
30 | > 주의: 본 스크립트를 설치 및 사용하며 브라우저 과부하로 인한 응답 없음/뻗음으로 인한 데이터 손실, 보안 이슈, 기타 발생하는 다른 문제에 대하여 개발자는 책임지지 않음(보고된 문제는 없음)
31 | > 본 스크립트는 Tampermonkey 외의 스크립트 매니저에서는 정상 동작하지 않을 수 있으며, Chrome 계열 브라우저의 경우 Tampermonkey Beta 버전에 스크립트가 설치되어야 합니다.
32 |
33 | ## 자주묻는 질문
34 |
35 | - Q: 안 돼요.
--------------------------------------------------------------------------------
/CHZZK_User_Memo/README.md:
--------------------------------------------------------------------------------
1 | # CHZZK User Memo (Alpha Version)
2 |
3 | > **[공지] 테스트 버전이므로 별도 공지 없이 기능이 수정되거나 스크립트가 삭제될 수 있습니다.**
4 |
5 | - 치지직 채팅창에 유저 메모 기능을 추가합니다.
6 | - 악질 및 분탕 유저에 대한 관리 및 신고를 위한 목적으로 개발되었어요.
7 | - 누군가를 스토킹하는데 사용하지 않길 바라요!
8 |
9 | ## Preview
10 |
11 |
12 |
13 | - 메모가 존재하는 유저의 경우 닉네임 우측에 사용자가 설정한 별명을 표시해요.
14 | - 메모는 유저마다 고유한 UID를 기반으로 저장되므로, 닉네임이 변경되어도 유지돼요.
15 | - 사용자 이름을 클릭한 후 메모하기 버튼을 누르면 메모를 추가할 수 있어요.
16 | - 닉변 로그 또는 채팅 로그가 있는 경우 이를 확인하기 위한 버튼이 표시돼요. (추적 기능이 켜져있을 때)
17 |
18 | ### 메모 추가
19 |
20 |
21 |
22 | - 메모하기 버튼을 누르면 메모를 추가할 수 있어요.
23 | - 채팅창에 표시할 사용자 별명과, 상세 메모를 작성할 수 있어요.
24 | - 추적하기에 체크하는 경우, 채팅 로그와 닉변 로그를 저장해요.
25 |
26 | ### UID 복사
27 |
28 |
29 |
30 | - 채팅 가장 우측의 복사 버튼을 클릭하면 현재 닉네임, UID, 채팅 내용, 채팅 시간을 클립보드에 복사해요.
31 |
32 | ### 닉변 알림
33 |
34 |
35 |
36 | - 메모 되어있는 유저가 닉변한 후 채팅을 칠 때 알려줘요요.
37 |
38 | ### 메모 확인
39 |
40 |
41 |
42 |
43 |
44 | - 모든 메모 보기 버튼을 클릭하여 메모된 내용을 볼 수 있어요.
45 |
46 | ### 설정
47 |
48 |
49 |
50 | - 유저별 채팅과 닉변 로그를 저장할 개수를 설정할 수 있어요.
51 | - 로그가 지정된 수를 초과하는 경우 가장 오래된 것부터 삭제돼요.
52 | - 기본 값은 채팅 기록 30개, 닉변 기록 5개에요. 로그를 너무 많이 남기면 느려질 수도 있어요.
53 |
54 | ## Install
55 |
56 | 설치 방법을 설명합니다.
57 |
58 | ### STEP 1. ScriptManager
59 |
60 | 아래 리스트에서 본인이 사용 중인 브라우저에 맞는 링크에 접속한 후, 유저스크립트 관리 확장기능인 Tampermonkey 를 설치하세요.
61 |
62 | - Chrome - [Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)
63 | - Firefox - [Tampermonkey](https://addons.mozilla.org/ko/firefox/addon/tampermonkey/)
64 | - Opera - [Tampermonkey](https://addons.opera.com/extensions/details/tampermonkey-beta/)
65 | - Safari - [Tampermonkey](https://safari.tampermonkey.net/tampermonkey.safariextz)
66 | - Edge - [Tampermonkey](https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd)
67 |
68 | ### STEP 2. UserScript
69 |
70 | - 유저스크립트 관리 확장기능 설치 후 아래의 링크를 클릭하세요. 이후 뜨는 창에서 "설치" 버튼을 눌러 스크립트를 설치합니다.
71 | - [https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_User_Memo/CHZZK_User_Memo.user.js](https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_User_Memo/CHZZK_User_Memo.user.js)
72 |
73 | 이것으로 설치는 끝입니다. 즐겁게 사용하세요~
74 |
75 | > 주의: 본 스크립트를 설치 및 사용하며 브라우저 과부하로 인한 응답 없음/뻗음으로 인한 데이터 손실이나 기타 발생하는 다른 문제에 대하여 개발자는 책임지지 않음(보고된 문제는 없음)
76 | > 본 스크립트는 Tampermonkey 외의 스크립트 매니저에서는 정상 동작하지 않을 수 있습니다.
77 |
78 | ## Note
79 |
80 | - 코드의 80% 이상을 ChatGPT로 작성했어요. 예외처리 같은 것이 제대로 안 되어 있긴 한데 현재는 대충 잘 되는 것 같아요. 문제가 생기면 스크립트를 비활성화 하세요.
81 | - 수초마다 닉변하면서 닌자 분신술을 펼치며 분탕칠을 치는 녀석이 있어서 만들었어요.
82 |
83 | ### 0.0.2 - Dec. 7, 2024
84 |
85 | - 채팅에서 닉네임 클릭 시 UID가 출력되지 않는 문제 수정
86 |
87 | ### 0.0.1 - Aug. 16, 2024
88 |
89 | - 최초 커밋 (Alpha 버전)
90 |
91 | ## License
92 |
93 | MIT
94 |
95 | ## Happy??
96 |
97 |
98 |
--------------------------------------------------------------------------------
/Better_Multichzzk/Better_Multichzzk.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name Better_Multichzzk
3 | // @namespace Better_Multichzzk
4 | // @version 0.0.5
5 | // @description Better player for multichzzk
6 | // @author Nomo
7 | // @match https://multichzzk.tv/*
8 | // @match https://mul.live/*
9 | // @match https://chzzk.naver.com/*?multichzzk
10 | // @supportURL https://github.com/nomomo/Chzzk_Scripts/issues
11 | // @homepage https://github.com/nomomo/Chzzk_Scripts/
12 | // @downloadURL https://github.com/nomomo/Chzzk_Scripts/raw/main/Better_Multichzzk/Better_Multichzzk.user.js
13 | // @updateURL https://github.com/nomomo/Chzzk_Scripts/raw/main/Better_Multichzzk/Better_Multichzzk.user.js
14 | // ==/UserScript==
15 |
16 | (function () {
17 | 'use strict';
18 | let debug = false;
19 |
20 | let url = document.location.href;
21 | if (url.indexOf("//multichzzk.tv/") !== -1 || url.indexOf("//mul.live/") !== -1) {
22 | let iframes = document.querySelectorAll('iframe');
23 | if (debug) console.log("iframes", iframes);
24 |
25 | iframes.forEach(function (iframe) {
26 | if (iframe.src.indexOf('//chzzk.naver.com/') !== -1 && iframe.src.indexOf('?multichzzk') === -1) {
27 | iframe.src = iframe.src + '?multichzzk';
28 | }
29 | });
30 | } else if (url.indexOf("//chzzk.naver.com/") !== -1) {
31 | let isTopWindow = window.self === window.top;
32 | if (isTopWindow) {
33 | return;
34 | }
35 |
36 | if (debug) console.log("chzzk embed", url);
37 |
38 | function waitForElement(selector, callback) {
39 | const existingElement = document.querySelector(selector);
40 |
41 | if (existingElement) {
42 | callback(existingElement);
43 | } else {
44 | const observer = new MutationObserver((mutationsList) => {
45 | const targetElement = document.querySelector(selector);
46 | if (targetElement) {
47 | observer.disconnect();
48 | callback(targetElement);
49 | }
50 | });
51 |
52 | observer.observe(document.documentElement, {
53 | childList: true,
54 | subtree: true,
55 | });
56 | }
57 | }
58 |
59 | let player = undefined;
60 | let handleVideoReadyFired = false;
61 |
62 | let handleVideoReady = function(){
63 | if (handleVideoReadyFired) return;
64 | handleVideoReadyFired = true;
65 | let viewmode_buttons = document.querySelectorAll(".pzp-pc__viewmode-button");
66 | if(viewmode_buttons.length == 1){
67 | viewmode_buttons[0].click();
68 | }
69 | else{
70 | // 치즈나이프와의 충돌 방지
71 | for (let i = 0; i < viewmode_buttons.length; i++) {
72 | let button = viewmode_buttons[i];
73 | if (button.getAttribute('aria-label') === '넓은 화면') {
74 | button.click();
75 | break;
76 | }
77 | }
78 | }
79 | document.querySelector('[class^="live_chatting_header_button__"]').click();
80 | };
81 |
82 | waitForElement("video.webplayer-internal-video", function (node) {
83 | if (debug) console.log("found video player", node);
84 | player = node;
85 | if (player.readyState >= 2) {
86 | handleVideoReady();
87 | } else {
88 | player.addEventListener('loadedmetadata', function once() {
89 | player.removeEventListener('loadedmetadata', once);
90 | handleVideoReady();
91 | });
92 | }
93 | player.muted = true;
94 | });
95 |
96 | }
97 |
98 | })();
--------------------------------------------------------------------------------
/CHZZK_Always_Awake/CHZZK_Always_Awake.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name CHZZK_Always_Awake
3 | // @namespace CHZZK_Always_Awake
4 | // @version 0.0.1
5 | // @description Pretends to be active even when the tab is inactive.
6 | // @author Nomo
7 | // @match https://chzzk.naver.com/*
8 | // @supportURL https://github.com/nomomo/Chzzk_Scripts/issues
9 | // @homepage https://github.com/nomomo/Chzzk_Scripts/
10 | // @downloadURL https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Always_Awake/CHZZK_Always_Awake.user.js
11 | // @updateURL https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Always_Awake/CHZZK_Always_Awake.user.js
12 | // @grant unsafeWindow
13 | // @run-at document-start
14 | // ==/UserScript==
15 |
16 | (async () => {
17 | 'use strict';
18 | var DEBUG = false;
19 | var NOMO_DEBUG = function ( /**/ ) {
20 | if (!DEBUG) return;
21 | var args = arguments, args_length = args.length, args_copy = args;
22 | for (let i = args_length; i > 0; i--) args[i] = args_copy[i - 1];
23 | args[0] = "[CAA] ";
24 | args.length = args_length + 1;
25 | console.log.apply(console, args);
26 | };
27 | var date_n = Number(new Date());
28 |
29 | NOMO_DEBUG("GM_SETTINGS.disable_visibilitychange: true");
30 | try{
31 | Object.defineProperty(document, 'hidden', {
32 | value: false,
33 | writable: false
34 | });
35 | }
36 | catch(e){
37 | NOMO_DEBUG("disable_visibilitychange error - hidden redefine", e);
38 | }
39 |
40 | try{
41 | Object.defineProperty(document, 'visibilityState', {
42 | value: 'visible',
43 | writable: false
44 | });
45 | }
46 | catch(e){
47 | NOMO_DEBUG("disable_visibilitychange error - visibilityState redefine", e);
48 | }
49 |
50 | try{
51 | Object.defineProperty(document, 'webkitVisibilityState', {
52 | value: 'visible',
53 | writable: false
54 | });
55 | }
56 | catch(e){
57 | NOMO_DEBUG("disable_visibilitychange error - webkitVisibilityState redefine", e);
58 | }
59 |
60 | try{
61 | document.dispatchEvent(new Event('visibilitychange'));
62 | }
63 | catch(e){
64 | NOMO_DEBUG("disable_visibilitychange error - visibilitychange dispatchEvent", e);
65 | }
66 |
67 | try{
68 | document.hasFocus = function () {
69 | return true;
70 | };
71 | }
72 | catch(e){
73 | NOMO_DEBUG("disable_visibilitychange error - hasFocus return true", e);
74 | }
75 |
76 | try{
77 | unsafeWindow["_addEventListener_" + date_n] = unsafeWindow.addEventListener;
78 | unsafeWindow.addEventListener = function (a, b, c) {
79 | if (a === "visibilitychange" || a === "blur" || a === "webkitvisibilitychange") {
80 | return;
81 | }
82 |
83 | if (c == undefined){
84 | c = false;
85 | }
86 | unsafeWindow["_addEventListener_" + date_n](a, b, c);
87 | };
88 | }
89 | catch(e){
90 | NOMO_DEBUG("disable_visibilitychange error - overwrite window addEventListener", e);
91 | }
92 |
93 | try{
94 | unsafeWindow.document["_addEventListener_" + date_n] = unsafeWindow.document.addEventListener;
95 | unsafeWindow.document.addEventListener = function (a, b, c) {
96 | if (a === "visibilitychange" || a === "blur" || a === "webkitvisibilitychange") {
97 | return;
98 | }
99 |
100 | if (c == undefined){
101 | c = false;
102 | }
103 | unsafeWindow.document["_addEventListener_" + date_n](a, b, c);
104 | };
105 | }
106 | catch(e){
107 | NOMO_DEBUG("disable_visibilitychange error - overwrite document addEventListener", e);
108 | }
109 |
110 | })();
111 |
--------------------------------------------------------------------------------
/CHZZK_sign_in_iframe/CHZZK_sign_in_iframe.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name CHZZK_sign_in_iframe
3 | // @namespace CHZZK_sign_in_iframe
4 | // @version 0.0.2
5 | // @description iframe 으로 삽입된 CHZZK 페이지에서 로그인이 유지되도록 합니다.
6 | // @author Nomo
7 | // @match https://chzzk.naver.com/*
8 | // @supportURL https://github.com/nomomo/Chzzk_Scripts/issues
9 | // @homepage https://github.com/nomomo/Chzzk_Scripts/
10 | // @downloadURL https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_sign_in_iframe/CHZZK_sign_in_iframe.user.js
11 | // @updateURL https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_sign_in_iframe/CHZZK_sign_in_iframe.user.js
12 | // @grant GM_cookie
13 | // @grant GM.cookie
14 | // @run-at document-start
15 | // ==/UserScript==
16 |
17 | (function () {
18 | 'use strict';
19 |
20 | var DEBUG = false;
21 | const targetCookies = ["NID_SES", "NID_AUT", "NID_JKL"];
22 |
23 | if (!GM.cookie) {
24 | console.log("GM.cookie is not supported.");
25 | return;
26 | }
27 |
28 | if (DEBUG) {
29 | GM.cookie.list({}).then(function (cookies, error) {
30 | console.log("get all coockies", cookies, error);
31 | });
32 | }
33 |
34 | function setCookieSameSiteNone(targetCookieName, options) {
35 | GM.cookie.list({
36 | name: targetCookieName
37 | }).then(function (cookies, error) {
38 | if (!error) {
39 | for (let i = 0; i < cookies.length; i++) {
40 | if(cookies[i].sameSite == "no_restriction" && cookies[i].secure == true){
41 | continue;
42 | }
43 |
44 | // if (DEBUG) console.log("Try to delete old cookie", cookies[0]);
45 | // GM_cookie.delete(cookies[i], function () {
46 |
47 | // cookies[i].sameSite = "no_restriction";
48 | // cookies[i].secure = true;
49 |
50 | // if (DEBUG) console.log("Try to set new cookie", cookies[0]);
51 | // GM.cookie.set(cookies[i])
52 | // .then(function () {
53 | // if (DEBUG) console.log('set cookie done');
54 | // }, function (error) {
55 | // if (DEBUG) console.log('set cookie error', error);
56 | // });
57 |
58 | // })
59 |
60 | cookies[i].sameSite = "no_restriction";
61 | cookies[i].secure = true;
62 |
63 | if (DEBUG) console.log("Try to set new cookie", cookies[0]);
64 | GM.cookie.set(cookies[i])
65 | .then(function () {
66 | if (DEBUG) console.log('set cookie done');
67 | }, function (error) {
68 | if (DEBUG) console.log('set cookie error', error);
69 | });
70 | }
71 | }
72 | else{
73 | if (DEBUG) console.log('error from GM.cookie.list of setCookieSameSiteNone');
74 | }
75 | });
76 | }
77 |
78 | for (const ck of targetCookies) {
79 | setCookieSameSiteNone(ck);
80 | }
81 |
82 | let isTopWindow = window.self === window.top;
83 |
84 | // 쿠키 변경 시 갱신
85 | if (cookieStore) {
86 | cookieStore.addEventListener("change", function (event) {
87 | if (DEBUG) console.log("cookie change event", event.changed);
88 |
89 | if (event.changed.length > 0 && event.changed[0].sameSite != "none" && targetCookies.includes(event.changed[0].name)) {
90 | setCookieSameSiteNone(event.changed[0].name);
91 | }
92 |
93 | });
94 | } else {
95 | console.log("cookieStore is not supported.");
96 | if(isTopWindow){
97 | setInterval(function () {
98 | for (const ck of targetCookies) {
99 | setCookieSameSiteNone(ck);
100 | }
101 | }, 250);
102 | }
103 | }
104 |
105 | // 전혀 상관없는 다른 창에서 쿠키 변경된 경우 때문에 문제 발생하는 경우를 방지
106 | if(!isTopWindow){
107 | document.addEventListener("DOMContentLoaded", function() {
108 | setTimeout(function(){
109 | setInterval(function () {
110 | for (const ck of targetCookies) {
111 | setCookieSameSiteNone(ck);
112 | }
113 | }, 250);
114 | },2000);
115 | });
116 | }
117 |
118 | })();
--------------------------------------------------------------------------------
/CHZZK_Restore_Blind_Chat/CHZZK_Restore_Blind_Chat.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name CHZZK Restore Blind Chat
3 | // @namespace CHZZK_Restore_Blind_Chat
4 | // @version 0.0.3
5 | // @description Restore original chat messages when they are hidden by the admin
6 | // @author Nomo
7 | // @match https://chzzk.naver.com/*
8 | // @supportURL https://github.com/nomomo/Chzzk_Scripts/issues
9 | // @homepage https://github.com/nomomo/Chzzk_Scripts/
10 | // @downloadURL https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Restore_Blind_Chat/CHZZK_Restore_Blind_Chat.user.js
11 | // @updateURL https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Restore_Blind_Chat/CHZZK_Restore_Blind_Chat.user.js
12 | // @grant none
13 | // ==/UserScript==
14 |
15 |
16 | (function() {
17 | 'use strict';
18 |
19 | // Function to check if class name starts with a specific prefix
20 | function classStartsWith(element, prefix) {
21 | return element && Array.from(element.classList).some(className => className.startsWith(prefix));
22 | }
23 |
24 | // Check and update whether autoscroll is currently active
25 | let autoscroll = true;
26 | function updatechatAutoScroll(){
27 | const scrollButtonChattingElement = document.querySelector('[class*="live_chatting_scroll_button_chatting__"]');
28 | if (scrollButtonChattingElement) {
29 | autoscroll = false;
30 | }
31 | else {
32 | autoscroll = true;
33 | }
34 | }
35 |
36 | // Scroll down the chatbox
37 | function chatScrollToBottom() {
38 | const chattingListWrapperElement = document.querySelector('[class*="live_chatting_list_wrapper__"]');
39 | if (chattingListWrapperElement && autoscroll) {
40 | chattingListWrapperElement.scrollTop = chattingListWrapperElement.scrollHeight + 1000000;
41 | }
42 | }
43 |
44 | // Function to observe individual chat elements for changes in attributes
45 | function observeChatAttributes(node) {
46 | if (node.nodeType === 1 && classStartsWith(node, 'live_chatting_message_container__')) {
47 | // Create a MutationObserver to watch for attribute changes
48 | const attributeObserver = new MutationObserver(mutations => {
49 | mutations.forEach(mutation => {
50 | if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
51 | const target = mutation.target;
52 | if (classStartsWith(target, 'live_chatting_message_is_hidden__')) {
53 | const parentElement = target.closest('[class^="live_chatting_list_item__"]');
54 | const messageTextElem = target.querySelector('[class^="live_chatting_message_text__"]');
55 | if (parentElement && messageTextElem) {
56 | const originalMessage = parentElement.getAttribute('data-original-message');
57 | if (originalMessage) {
58 | updatechatAutoScroll();
59 | messageTextElem.innerText = `[블라인드된 메시지] ${originalMessage}`;
60 | chatScrollToBottom();
61 | }
62 | }
63 | }
64 | }
65 | });
66 | });
67 |
68 | attributeObserver.observe(node, { attributes: true });
69 | }
70 | }
71 |
72 | // Function to observe individual chat elements
73 | function observeChatElements(node) {
74 | if (node.nodeType === 1 && classStartsWith(node, 'live_chatting_list_item__')) {
75 | const messageTextElem = node.querySelector('[class^="live_chatting_message_text__"]');
76 | if (messageTextElem) {
77 | const messageIdElem = node.querySelector('[class^="live_chatting_username_nickname__"]');
78 | if (messageTextElem && messageIdElem) {
79 | const messageText = messageTextElem.innerText;
80 | // Store the original message in a data attribute
81 | node.setAttribute('data-original-message', messageText);
82 | // Observe the container for attribute changes
83 | const messageContainer = node.querySelector('[class^="live_chatting_message_container__"]');
84 | if (messageContainer) {
85 | observeChatAttributes(messageContainer);
86 | }
87 | }
88 | }
89 | }
90 | }
91 |
92 | // Main observer to detect chat elements in the body
93 | const mainObserver = new MutationObserver(mutations => {
94 | mutations.forEach(mutation => {
95 | mutation.addedNodes.forEach(node => {
96 | observeChatElements(node);
97 | });
98 | });
99 | });
100 |
101 | // Start observing the body for chat elements
102 | function startObserving() {
103 | const mainContainer = document.body;
104 | if (mainContainer) {
105 | mainObserver.observe(mainContainer, { childList: true, subtree: true });
106 |
107 | // Check if chat elements already exist
108 | const existingChatElements = document.querySelectorAll('[class^="live_chatting_list_item__"]');
109 | existingChatElements.forEach(node => observeChatElements(node));
110 | } else {
111 | setTimeout(startObserving, 1000);
112 | }
113 | }
114 |
115 | startObserving();
116 | })();
--------------------------------------------------------------------------------
/CHZZK_Degul_Interpreter/CHZZK_Degul_Interpreter.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name CHZZK 데굴어 통역기
3 | // @namespace CHZZK_Degul_Interpreter
4 | // @version 0.0.2
5 | // @description 치지직에서 '데굴'을 실제 뜻으로 번역해 보여줍니다.
6 | // @author Nomo
7 | // @match https://chzzk.naver.com/*
8 | // @homepageURL https://github.com/nomomo/Chzzk_Scripts/CHZZK_Degul_Interpreter/
9 | // @downloadURL https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Degul_Interpreter/CHZZK_Degul_Interpreter.user.js
10 | // @updateURL https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Degul_Interpreter/CHZZK_Degul_Interpreter.user.js
11 | // @run-at document-end
12 | // @grant none
13 | // ==/UserScript==
14 |
15 | (() => {
16 | 'use strict';
17 |
18 | // --- 동적으로 변하는 입력창 클래스의 접두사
19 | const DYNAMIC_CLASS_PREFIXES = ['live_chatting_input_input__'];
20 |
21 | // --- 스킵할 셀렉터(명시)
22 | const SKIP_SELECTORS = [
23 | '[contenteditable="true"]',
24 | '[role="textbox"]',
25 | 'input',
26 | 'textarea',
27 | 'script',
28 | 'style',
29 | ];
30 | const SKIP_SELECTOR_STR = SKIP_SELECTORS.join(',');
31 |
32 | /**
33 | * 텍스트 치환:
34 | * A) 단어형
35 | * - '데…굴' → '시…발', '떼…굴' → '씨…발'
36 | * - '데…꿀' → '시…빨', '떼…꿀' → '씨…빨'
37 | * B) 자모 축약형
38 | * - 'ㄷ…ㄱ' → 'ㅅ…ㅂ', 'ㄸ…ㄱ' → 'ㅆ…ㅂ'
39 | * - 'ㄷ…ㄲ' → 'ㅅ…ㅃ', 'ㄸ…ㄲ' → 'ㅆ…ㅃ'
40 | *
41 | * 가운데의 특수문자/공백 시퀀스(…)는 그대로 보존.
42 | */
43 | function replaceText(s) {
44 | // 단어형(데/떼 … 꿀/굴)
45 | let out = s.replace(/(떼|데)([^가-힣A-Za-z0-9]*)(꿀|굴)/gu, (_, head, mid, tail) => {
46 | const first = head === '떼' ? '씨' : '시';
47 | const last = tail === '꿀' ? '빨' : '발';
48 | return first + mid + last;
49 | });
50 |
51 | // 자모 축약형(ㄷ/ㄸ … ㄱ/ㄲ)
52 | out = out.replace(/(ㄸ|ㄷ)([^가-힣A-Za-z0-9]*)(ㄲ|ㄱ)/gu, (_, head, mid, tail) => {
53 | const first = head === 'ㄸ' ? 'ㅆ' : 'ㅅ';
54 | const last = tail === 'ㄲ' ? 'ㅃ' : 'ㅂ';
55 | return first + mid + last;
56 | });
57 |
58 | return out;
59 | }
60 |
61 | /** 요소가 주어진 클래스 접두사 중 하나를 갖는지 확인 */
62 | function hasAnyClassWithPrefix(el, prefixes) {
63 | if (!(el instanceof Element) || !el.classList || el.classList.length === 0) return false;
64 | for (const cls of el.classList) {
65 | for (const p of prefixes) if (cls.startsWith(p)) return true;
66 | }
67 | return false;
68 | }
69 |
70 | /** 스킵 여부 판단: 명시 셀렉터 + 동적 클래스 접두사 + isContentEditable 백업 */
71 | function isSkippable(el) {
72 | if (!(el instanceof Element)) return false;
73 | if (el.matches(SKIP_SELECTOR_STR)) return true; // ✅ 명시 셀렉터 우선
74 | if (hasAnyClassWithPrefix(el, DYNAMIC_CLASS_PREFIXES)) return true; // ✅ CHZZK 입력창 해시 클래스
75 | if (el.isContentEditable) return true; // ✅ 백업(속성 변형 대비)
76 | return false;
77 | }
78 |
79 | /** 노드가 스킵 영역 내부(조상 포함)인지 검사 (Shadow DOM 포함) */
80 | function isInsideSkippable(node) {
81 | let n = node;
82 | while (n) {
83 | if (n instanceof Element && isSkippable(n)) return true;
84 | const p = n.parentNode;
85 | if (p && p.nodeType === 11 /* ShadowRoot */ && p.host) {
86 | n = p.host; // shadow -> host
87 | } else {
88 | n = n.parentNode || null;
89 | }
90 | }
91 | return false;
92 | }
93 |
94 | /** 텍스트 노드 순회 치환 (입력/편집 영역 제외) */
95 | function walkAndReplace(root) {
96 | if (!root) return;
97 | const walker = document.createTreeWalker(
98 | root,
99 | NodeFilter.SHOW_TEXT,
100 | {
101 | acceptNode: (t) => {
102 | if (!t.nodeValue || !t.parentNode) return NodeFilter.FILTER_REJECT;
103 | return isInsideSkippable(t) ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT;
104 | },
105 | },
106 | );
107 |
108 | const edits = [];
109 | for (let n = walker.nextNode(); n; n = walker.nextNode()) {
110 | const before = n.nodeValue;
111 | const after = replaceText(before);
112 | if (before !== after) edits.push([n, after]);
113 | }
114 | for (const [n, after] of edits) n.nodeValue = after;
115 | }
116 |
117 | /** DOM 변경 관찰: 추가/수정된 텍스트만 처리 */
118 | function observe(root) {
119 | if (!root) return;
120 | const mo = new MutationObserver((muts) => {
121 | for (const m of muts) {
122 | if (m.type === 'characterData' && m.target && m.target.nodeType === 3) {
123 | const t = m.target;
124 | if (isInsideSkippable(t)) continue; // 입력/편집 영역은 무시
125 | const before = t.nodeValue;
126 | const after = replaceText(before);
127 | if (before !== after) t.nodeValue = after;
128 | continue;
129 | }
130 | for (const n of m.addedNodes) {
131 | if (n.nodeType === 3) {
132 | if (isInsideSkippable(n)) continue;
133 | const before = n.nodeValue;
134 | const after = replaceText(before);
135 | if (before !== after) n.nodeValue = after;
136 | } else if (n.nodeType === 1) {
137 | if (isInsideSkippable(n)) continue;
138 | walkAndReplace(n);
139 | if (n.shadowRoot) {
140 | walkAndReplace(n.shadowRoot);
141 | observe(n.shadowRoot);
142 | }
143 | }
144 | }
145 | }
146 | });
147 | mo.observe(root, { subtree: true, childList: true, characterData: true });
148 | }
149 |
150 | /** 부트스트랩 */
151 | function boot() {
152 | const docRoot = document.documentElement || document.body;
153 | walkAndReplace(docRoot);
154 | observe(docRoot);
155 |
156 | // 열린 Shadow DOM도 초기 스캔/관찰
157 | document.querySelectorAll('*').forEach((el) => {
158 | if (el.shadowRoot) {
159 | walkAndReplace(el.shadowRoot);
160 | observe(el.shadowRoot);
161 | }
162 | });
163 | }
164 |
165 | if (document.readyState === 'loading') {
166 | document.addEventListener('DOMContentLoaded', boot, { once: true });
167 | } else {
168 | boot();
169 | }
170 | })();
171 |
--------------------------------------------------------------------------------
/CHZZK_Never_Stop_At_Start/CHZZK_Never_Stop_At_Start.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name CHZZK Never Stop At Start
3 | // @namespace CHZZK_Never_Stop_At_Start
4 | // @version 0.0.2
5 | // @description CHZZK_Never_Stop_At_Start
6 | // @author Nomo
7 | // @match https://chzzk.naver.com/*
8 | // @supportURL https://github.com/nomomo/Chzzk_Scripts/issues
9 | // @homepage https://github.com/nomomo/Chzzk_Scripts/
10 | // @downloadURL https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Never_Stop_At_Start/CHZZK_Never_Stop_At_Start.user.js
11 | // @updateURL https://github.com/nomomo/Chzzk_Scripts/raw/main/CHZZK_Never_Stop_At_Start/CHZZK_Never_Stop_At_Start.user.js
12 | // @grant none
13 | // ==/UserScript==
14 |
15 | (function() {
16 | 'use strict';
17 |
18 | /*
19 | * arrive.js
20 | * v2.4.1
21 | * https://github.com/uzairfarooq/arrive
22 | * MIT licensed
23 | *
24 | * Copyright (c) 2014-2017 Uzair Farooq
25 | */
26 | var Arrive=function(e,t,n){"use strict";function r(e,t,n){l.addMethod(t,n,e.unbindEvent),l.addMethod(t,n,e.unbindEventWithSelectorOrCallback),l.addMethod(t,n,e.unbindEventWithSelectorAndCallback)}function i(e){e.arrive=f.bindEvent,r(f,e,"unbindArrive"),e.leave=d.bindEvent,r(d,e,"unbindLeave")}if(e.MutationObserver&&"undefined"!=typeof HTMLElement){var o=0,l=function(){var t=HTMLElement.prototype.matches||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector;return{matchesSelector:function(e,n){return e instanceof HTMLElement&&t.call(e,n)},addMethod:function(e,t,r){var i=e[t];e[t]=function(){return r.length==arguments.length?r.apply(this,arguments):"function"==typeof i?i.apply(this,arguments):n}},callCallbacks:function(e,t){t&&t.options.onceOnly&&1==t.firedElems.length&&(e=[e[0]]);for(var n,r=0;n=e[r];r++)n&&n.callback&&n.callback.call(n.elem,n.elem);t&&t.options.onceOnly&&1==t.firedElems.length&&t.me.unbindEventWithSelectorAndCallback.call(t.target,t.selector,t.callback)},checkChildNodesRecursively:function(e,t,n,r){for(var i,o=0;i=e[o];o++)n(i,t,r)&&r.push({callback:t.callback,elem:i}),i.childNodes.length>0&&l.checkChildNodesRecursively(i.childNodes,t,n,r)},mergeArrays:function(e,t){var n,r={};for(n in e)e.hasOwnProperty(n)&&(r[n]=e[n]);for(n in t)t.hasOwnProperty(n)&&(r[n]=t[n]);return r},toElementsArray:function(t){return n===t||"number"==typeof t.length&&t!==e||(t=[t]),t}}}(),c=function(){var e=function(){this._eventsBucket=[],this._beforeAdding=null,this._beforeRemoving=null};return e.prototype.addEvent=function(e,t,n,r){var i={target:e,selector:t,options:n,callback:r,firedElems:[]};return this._beforeAdding&&this._beforeAdding(i),this._eventsBucket.push(i),i},e.prototype.removeEvent=function(e){for(var t,n=this._eventsBucket.length-1;t=this._eventsBucket[n];n--)if(e(t)){this._beforeRemoving&&this._beforeRemoving(t);var r=this._eventsBucket.splice(n,1);r&&r.length&&(r[0].callback=null)}},e.prototype.beforeAdding=function(e){this._beforeAdding=e},e.prototype.beforeRemoving=function(e){this._beforeRemoving=e},e}(),a=function(t,r){var i=new c,o=this,a={fireOnAttributesModification:!1};return i.beforeAdding(function(n){var i,l=n.target;(l===e.document||l===e)&&(l=document.getElementsByTagName("html")[0]),i=new MutationObserver(function(e){r.call(this,e,n)});var c=t(n.options);i.observe(l,c),n.observer=i,n.me=o}),i.beforeRemoving(function(e){e.observer.disconnect()}),this.bindEvent=function(e,t,n){t=l.mergeArrays(a,t);for(var r=l.toElementsArray(this),o=0;o