Handlers Helper

Helper for protocol_hook.lua

  1. // ==UserScript==
  2. // @name Handlers Helper
  3. // @include *://*/*
  4. // @grant GM_getValue
  5. // @grant GM_setValue
  6. // @grant GM_deleteValue
  7. // @grant GM_addStyle
  8. // @grant GM_registerMenuCommand
  9. // @version 3.7
  10. // @author -
  11. // @description Helper for protocol_hook.lua
  12. // @namespace Violentmonkey Scripts
  13. // ==/UserScript==
  14.  
  15. //'iptv'
  16.  
  17. const guide = 'Value: pipe ytdl stream mpv iptv';
  18. const live_window_width = 400;
  19. const live_window_height = 640;
  20.  
  21. var total_direction = 4;
  22. var livechat = false;
  23. var hlsdomain = 'cdn.animevui.com';
  24. var UP = 'pipe';
  25. var DOWN = 'ytdl';
  26. var LEFT = 'stream';
  27. var RIGHT = 'mpv';
  28. var UP = GM_getValue('UP', UP);
  29. var DOWN = GM_getValue('DOWN', DOWN);
  30. var LEFT = GM_getValue('LEFT', LEFT);
  31. var RIGHT = GM_getValue('RIGHT', RIGHT);
  32. var hlsdomain = GM_getValue('hlsdomain', hlsdomain);
  33. var livechat = GM_getValue('livechat', livechat);
  34. var total_direction = GM_getValue('total_direction', total_direction);
  35. GM_registerMenuCommand('↑: ' + UP.toString(), function() {var p = window.prompt(guide, UP);if(!p){return;};GM_setValue('UP', p);window.location.reload();});
  36. GM_registerMenuCommand('↓: ' + DOWN.toString(), function() {var p = window.prompt(guide, DOWN);if(!p){return;};GM_setValue('DOWN', p);window.location.reload();});
  37. GM_registerMenuCommand('←: ' + LEFT.toString(), function() {var p = window.prompt(guide, LEFT);if(!p){return;};GM_setValue('LEFT', p);window.location.reload();});
  38. GM_registerMenuCommand('→: ' + RIGHT.toString(), function() {var p = window.prompt(guide, RIGHT);if(!p){return;};GM_setValue('RIGHT', p);window.location.reload();});
  39. GM_registerMenuCommand('HLS Force', function() {var p = window.prompt('Example: 1.com,2.com,3.com,4.com', hlsdomain);if(!p){return;};GM_setValue('hlsdomain', p);});
  40. GM_registerMenuCommand('Live Chat: ' + livechat.toString(), function() {var v = livechat;if(v == true){GM_setValue('livechat', false);}else{GM_setValue('livechat', true);};window.location.reload();});
  41. GM_registerMenuCommand('Total Direction: ' + total_direction.toString(), function() {var v = total_direction;if(v == 4){GM_setValue('total_direction', 8);}else{GM_setValue('total_direction', 4);};window.location.reload();});
  42.  
  43. console.log(UP, DOWN, LEFT, RIGHT, hlsdomain, livechat, total_direction);
  44.  
  45. var hlsdomain = hlsdomain.split(',');
  46. var collected_urls = {};
  47. function GM_getParentByTagName(el, tagName) {
  48. tagName = tagName.toLowerCase();
  49. if (el.tagName.toLowerCase() == tagName) {
  50. return el;
  51. }
  52. while (el && el.parentNode) {
  53. el = el.parentNode;
  54. if (el.tagName && el.tagName.toLowerCase() == tagName) {
  55. return el;
  56. }
  57. }
  58. return "undefined";
  59. }
  60.  
  61. function attachDrag(elem) {
  62.  
  63. function GM_btoaUrl(url) {
  64. return btoa(url).replace(/\//g, "_").replace(/\+/g, "-").replace(/\=/g, "");
  65. }
  66.  
  67. function popout(chaturl) {
  68. window.open(chaturl, "", "fullscreen=no,toolbar=no,titlebar=no,menubar=no,location=no,width=" + live_window_width + ",height=" + live_window_height);
  69. }
  70.  
  71. function livechatopener(url) {
  72. var nurl = new URL(url);
  73. if (nurl.href.indexOf('www.youtube.com/watch') != -1 || nurl.href.indexOf('m.youtube.com/watch') != -1) {
  74. popout("https://www.youtube.com/live_chat?is_popout=1&v=" + nurl.search.split("v=")[1]);
  75. } else if (nurl.href.match('https://.*?.twitch.tv/.')) {
  76. popout("https://www.twitch.tv/popout" + nurl.pathname + "/chat?popout=");
  77. } else if (nurl.href.match('https://.*?.nimo.tv/.')) {
  78. var streamid = document.querySelector('a[href="' + nurl.pathname + '"] .nimo-player.n-as-full').id.replace('home-hot-', '');
  79. popout("https://www.nimo.tv/popout/chat/" + streamid);
  80. }
  81. }
  82.  
  83. function EA(attr, type) {
  84. var url = '';
  85. var subs = '';
  86. var s = '';
  87. var app = 'play';
  88. var hls = false;
  89. console.log(attr, type)
  90. for (i in hlsdomain) {
  91. if (attr.indexOf(hlsdomain[i]) != -1 || document.domain.indexOf(hlsdomain[i]) != -1) {
  92. if (type == 'stream') {
  93. attr = attr.replace(/https?:/, 'hls:');
  94. }
  95. hls = true;
  96. }
  97.  
  98. }
  99. if (attr.startsWith('http') || attr.startsWith('hls')) {
  100. url = attr;
  101. } else if (attr.startsWith('mpv://')) {
  102. location.href = attr;
  103. return;
  104. }
  105. if (url == '') {
  106. url = location.href;
  107. }
  108. console.log(collected_urls);
  109. if (Object.keys(collected_urls).length > 0) {
  110. for (link in collected_urls) {
  111. console.log(link, collected_urls[link]);
  112. collected_urls[link].style.boxSizing = 'unset';
  113. collected_urls[link].style.border = 'unset';
  114. s += link + ' ';
  115. }
  116. s = s.trim(' ');
  117. console.log(s);
  118. //var s = collected_urls.join(" ");
  119. } else {
  120. var s = url;
  121. }
  122. collected_urls = {};
  123. if (type == 'pipe') {
  124. app = 'mpvy';
  125. }
  126. else if (type == 'iptv') {
  127. app = 'list';
  128. }
  129. else if (type == 'mpv' || type == 'vid') {
  130. app = 'play';
  131. }
  132. else {
  133. app = type;
  134. }
  135. var bs = GM_btoaUrl(s);
  136. var url2 = 'mpv://' + app + '/' + bs + '/' + "?referer=" + GM_btoaUrl(location.href);
  137. if (subs != '') {
  138. url2 = url2 + '?subs=' + GM_btoaUrl(subs);
  139. }
  140. if (hls == true) {
  141. url2 = url2 + '?hls=1';
  142. }
  143. if (app == 'stream' && livechat == true) {
  144. livechatopener(url);
  145. }
  146. console.log(url2);
  147. location.href = url2;
  148. }
  149.  
  150. // Define the enum-like directory
  151. const DirectionEnum = {
  152. RIGHT: 6,
  153. LEFT: 4,
  154. UP: 2,
  155. DOWN: 8,
  156. UP_LEFT: 1,
  157. UP_RIGHT: 3,
  158. DOWN_LEFT: 7,
  159. DOWN_RIGHT: 9
  160. };
  161.  
  162. function getDirection(x, y, cx, cy) {
  163. /*=================
  164. | |
  165. | 1↖ 2↑ 3↗ |
  166. | |
  167. | 4← 5 6→ |
  168. | |
  169. | 7↙ 8↓ 9↘ |
  170. | |
  171. |=================*/
  172. let d, t;
  173. if (cx == 0 && cy == 0) {
  174. return 5;
  175. }
  176. if ((cx - x) >= -50 && (cx - x) <= 50 && (cy - y) >= -50 && (cy - y) <= 50) {
  177. return 5;
  178. }
  179. // Change (4 == 4) to (8 == 4) to enable 8 directions
  180. if (total_direction == 4) { //4 directions
  181. if (Math.abs(cx - x) < Math.abs(cy - y)) {
  182. d = cy > y ? "8" : "2";
  183. } else {
  184. d = cx > x ? "6" : "4";
  185. }
  186. } else { //8 directions
  187. t = (cy - y) / (cx - x);
  188. if (-0.4142 <= t && t < 0.4142) d = cx > x ? '6' : "4";
  189. else if (2.4142 <= t || t < -2.4142) d = cy > y ? '8' : '2';
  190. else if (0.4142 <= t && t < 2.4142) d = cx > x ? '9' : '1';
  191. else d = cy > y ? '7' : '3';
  192. }
  193. return d;
  194. }
  195. elem.addEventListener('dragstart', function(e) {
  196. //console.log(e.target);
  197. //console.log(e.target.shadowRoot);
  198. /*if (e.target.nodeName != "A") {
  199. e.stopPropagation();
  200. e.stopImmediatePropagation();
  201. //e.preventDefault();
  202. }*/
  203. console.log('dragstart');
  204. var x1 = e.clientX;
  205. var y1 = e.clientY;
  206. var dragend = elem.addEventListener('dragend', function doEA(e) {
  207. var x2 = e.clientX;
  208. var y2 = e.clientY;
  209. var direction = getDirection(x1, y1, x2, y2);
  210. //if ((x2 - x1) >= -50 && (x2 - x1) <= 50 && (y2 - y1) >= -50 && (y2 - y1) <= 50) {direction = 5;console.log(5);}
  211. //if (e.target.nodeName == "A" && e.target.href.match(/youtube.com|youtu.be|streamable.com/)) {
  212. console.log('Direction: ' + direction);
  213. console.log(x1, y1, x2, y2, direction);
  214.  
  215. const targetHref = e.target.href || e.target.src;
  216.  
  217. switch (+direction) {
  218. case DirectionEnum.RIGHT:
  219. console.log('RIGHT: ' + targetHref);
  220. EA(targetHref, RIGHT);
  221. break;
  222. case DirectionEnum.LEFT:
  223. console.log('LEFT: ' + targetHref);
  224. EA(targetHref, LEFT);
  225. break;
  226. case DirectionEnum.UP:
  227. console.log('UP: ' + targetHref);
  228. EA(targetHref, UP);
  229. break;
  230. case DirectionEnum.DOWN:
  231. console.log('DOWN: ' + targetHref);
  232. EA(targetHref, DOWN);
  233. break;
  234.  
  235. case DirectionEnum.UP_LEFT:
  236. console.log('List: ' + targetHref);
  237. EA(targetHref, 'list');
  238. break;
  239. case DirectionEnum.UP_RIGHT:
  240. case DirectionEnum.DOWN_LEFT:
  241. case DirectionEnum.DOWN_RIGHT:
  242. default:
  243. break;
  244. }
  245. //}
  246. console.log(direction);
  247. this.removeEventListener('dragend', doEA);
  248. }, false);
  249. }, false);
  250. }
  251.  
  252. var count = 0;
  253. var mouseIsDown = false;
  254. var held = false;
  255. document.addEventListener("mousedown", function (e) {
  256. var link = GM_getParentByTagName(e.target, 'A');
  257. if (link.nodeName == 'A') {
  258.  
  259. mouseIsDown = true;
  260. document.addEventListener("mouseup", function mouseup(e) {
  261. mouseIsDown = false;
  262. this.removeEventListener('mouseup', mouseup);
  263. });
  264. document.addEventListener("contextmenu", function contextmenu(e) {
  265. if (held == true) {
  266. held = false;
  267. e.preventDefault();
  268. }
  269. held = false;
  270. this.removeEventListener('contextmenu', contextmenu);
  271. });
  272. if (e.button === 2) {
  273. setTimeout(function () {
  274. if (mouseIsDown) {
  275. if (collected_urls[link.href] == undefined) {
  276. //var ele = GM_eleTOPele(e.target);
  277. //document.body.appendChild(ele);
  278. //collected_urls[link.href] = ele;
  279. collected_urls[link.href] = e.target;
  280. e.target.style.boxSizing = 'border-box';
  281. e.target.style.border = 'solid yellow 4px';
  282. //popup('Added: ' + link.href, e.clientX, e.clientY)
  283. } else {
  284. //collected_urls[link.href].parentNode.removeChild(collected_urls[link.href]);
  285. collected_urls[link.href].style.boxSizing = 'unset';
  286. collected_urls[link.href].style.border = 'unset';
  287. delete collected_urls[link.href];
  288. //e.target.style.boxSizing = 'unset';
  289. //e.target.style.border = 'unset';
  290. }
  291. console.log(collected_urls);
  292. count = 0;
  293. mouseIsDown = false;
  294. held = true;
  295. }
  296. }, 200);
  297. }
  298. }
  299.  
  300. });
  301.  
  302. attachDrag(document);
  303. var attachedeles = [];
  304. document.addEventListener('mouseover', function(e) {
  305. if (e.target.shadowRoot) {
  306. if (attachedeles.includes(e.target) == false) {
  307. console.log(attachedeles);
  308. attachedeles.push(e.target);
  309. attachDrag(e.target.shadowRoot);
  310. }
  311. }
  312. });
  313.  
  314. if (document.domain == 'www.youtube.com' || document.domain == 'm.youtube.com') {
  315. let state = GM_getValue('hh_mobile', 'unset');
  316. let dm = location.host || '';
  317. let dmc = dm.charAt(0) || '';
  318. /*if (state == true && dmc == 'w') {
  319. location.host = location.host.replace('www.youtube.com', 'm.youtube.com');
  320. } else if (state == false && dmc == 'm') {
  321. location.host = location.host.replace('m.youtube.com', 'www.youtube.com');
  322. }*/
  323. function addMenuCommand(s, url, b) {
  324. GM_registerMenuCommand(s, function () {
  325. if (b == true) {
  326. if (url.indexOf('m.youtube.com') != -1) {
  327. GM_setValue('hh_mobile', true);
  328. } else if (url.indexOf('www.youtube.com') != -1) {
  329. GM_setValue('hh_mobile', false);
  330. }
  331. } else {
  332. GM_deleteValue('hh_mobile');
  333. }
  334. location.replace(url);
  335. });
  336. }
  337. if (dmc == 'w') {
  338. addMenuCommand("Switch to YouTube Mobile persistently", "https://m.youtube.com/?persist_app=1&app=m", true);
  339. addMenuCommand("Switch to YouTube Mobile temporarily", "https://m.youtube.com/?persist_app=0&app=m", false);
  340. } else if (dmc == 'm') {
  341. addMenuCommand("Switch to YouTube Dekstop persistently", "http://www.youtube.com/?persist_app=1&app=desktop", true);
  342. addMenuCommand("Switch to YouTube Dekstop temporarily", "http://www.youtube.com/?persist_app=0&app=desktop", false);
  343. }
  344. if (dmc == 'm') {
  345. GM_addStyle('ytm-rich-item-renderer {width: 33%!important;margin: 1px!important;padding: 0px!important;}');
  346. }
  347. }