NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Acc Chat logger // @namespace http://tampermonkey.net/ // @version 0.0.3 // @copyright 2023, Ezekiel (https://openuserjs.org/users/Ezekiel) // @license GPL-3.0-or-later // @description AAC Chat logger // @author Ezekiel // @include /^https?:\/\/(www\.)?anime\.academy\/chat/ // @icon https://www.google.com/s2/favicons?domain=anime.academy // @grant none // ==/UserScript== (async function () { 'use strict'; /************************************ * * * CSS * * ************************************/ function addGlobalStyle(css) { let head, style; head = document.getElementsByTagName('head')[0]; if (!head) { return; } style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = css; head.appendChild(style); } addGlobalStyle( '.autocomplete-flex {' + ' background-color: #484b52;' + ' font-weight: 600;' + ' display: flex;' + ' align-items: center;' + ' gap: 10px;' + ' padding: 5px;' + '}' + '.autocomplete-flex:hover {' + ' background-color: #5f646e;' + '}' + '' + '.autocomplete-flex:focus {' + ' background-color: #5f646e;' + '}' + '' + '.name-link:hover {' + ' text-decoration: none;' + '}' + '.autocomplete-icon {' + ' width: 45px !important;' + ' height: 45px !important;' + ' border-radius: 50%;' + '}' + '.chatMessage {' + ' transition: padding 0.4s ease 0s;' + '}' + '.chatMessage:hover {' + ' padding-top: 5px;' + ' padding-bottom: 5px;' + ' position: relative;' + ' background-color: #5f646e !important;' + ' border-radius: 3px;' + ' transition: padding 0.4s ease 0s;' + '}' + '.messageIcons {' + ' display: flex;' + ' justify-content: center;' + ' align-items: center;' + ' height: 32px;' + ' width: 32px;' + ' background-color: #484b52;' + ' position: absolute;' + ' right: 0;' + ' top: -20px;' + ' display: none;' + ' border-radius: 3px;' + '}' + '.messageIcons:hover {' + ' background-color: #5f646e;' + ' filter: drop-shadow(5px 7px 14px black);' + '}' + '' + '.collapsible-wrap {' + ' margin: 10px 0 10px 0;' + '}' + '' + '.collapsible-button {' + ' cursor: pointer;' + ' padding: 18px;' + ' width: 100%;' + ' text-align: left;' + ' outline: none;' + ' font-size: 15px;' + '}' + '' + '.collapsible-button:focus {' + ' transition: background-color 0.5s ease;' + ' background-color: #3e1e80 !important;' + '}' + '' + '.collapsible-button:hover {' + ' transition: background-color 0.5s ease;' + '}' + '' + '.active {' + ' border-bottom-right-radius: 0 !important;' + ' border-bottom-left-radius: 0 !important;' + ' background-color: #3e1e80 !important;' + '}' + '' + '.collapsible-button:after {' + " content: '\\002B';" + ' font-weight: bold;' + ' float: right;' + ' margin-left: 5px;' + '}' + '' + '.active:after {' + " content: '\\2212';" + '}' + '' + '.collapsible-content {' + ' padding: 0 10px;' + ' max-height: 0;' + ' overflow: hidden;' + ' transition: max-height 0.2s ease-out;' + ' background-color: #2c2f33;' + ' border-bottom-left-radius: 3px;' + ' border-bottom-right-radius: 3px;' + '}' + '' + '.avatar-grid {' + ' width: 100%;' + ' display: grid;' + ' grid-template-columns: repeat(auto-fill, 8em);' + ' grid-gap: 10px 15px;' + '}' + '' + '.avatar-div {' + ' height: 80px;' + ' width: 80px;' + ' display: flex;' + ' align-items: center;' + ' justify-content: center;' + ' gap: 5px;' + '}' + '' + '.avatar-div:hover {' + ' background-color: #484b52;' + ' transition: background-color 0.5s ease;' + ' border-radius: 3px;' + '}' + '' + '.avatarIcon {' + ' height: 20px;' + ' width: 20px;' + ' background-color: #3e1e80;' + ' border-radius: 50%;' + ' display: none;' + ' align-items: center;' + ' justify-content: center;' + '}' + '' + '.avatarIcon:hover {' + ' background-color: #6b36d9;' + ' filter: drop-shadow(5px 7px 14px #2c2f33);' + ' transition: background-color 0.5s ease;' + '}' + '' + '.ionicon {' + ' width: 13px;' + ' height: 13px;' + ' fill: #ddd;' + '}' + '' + '.collection-selection {' + ' position: absolute;' + ' z-index: 10000;' + ' margin-left: auto;' + ' margin-right: auto;' + ' right: 0;' + ' left: 0;' + ' top: 80px;' + ' width: 300px;' + ' background-color: #484b52;' + ' padding: 10px;' + ' text-align: center;' + ' overflow: hidden scroll;' + ' border-radius: 3px;' + ' max-height: 200px;' + '}' + '' + '.collection-selectable {' + ' font-weight: 700;' + ' padding: 10px 0;' + ' margin-bottom: 5px;' + '}' + '' + '.collection-selectable:hover {' + ' background-color: #3e1e80;' + ' border-radius: 3px;' + ' transition: background-color 0.5s ease;' + ' filter: drop-shadow(5px 7px 14px #2c2f33);' + '}' + '' + '#createCollectionBtn {' + ' font-weight: 700;' + '}' + '' + '.removeCategory-btn {' + ' background-color: #fd2f2f;' + '}' + '' + '.request-delete-collection {' + ' position: absolute;' + ' z-index: 10000;' + ' margin-left: auto;' + ' margin-right: auto;' + ' right: 0;' + ' left: 0;' + ' top: 80px;' + ' width: 300px;' + ' background-color: #484b52;' + ' padding: 10px;' + ' text-align: center;' + ' overflow: hidden scroll;' + ' border-radius: 3px;' + ' max-height: 200px;' + '}' + '' + '.message-image {' + ' width: 100%;' + ' height: auto;' + ' border-radius: 3px;' + '}' + '' + '.message-image-container {' + ' margin-top: 5px;' + '}' + '' + '#username-results {' + ' border: none;' + ' max-height: 200px;' + ' overflow: hidden scroll;' + ' max-width: 30%;' + ' position: absolute;' + ' left: 0;' + ' right: 0;' + ' bottom: calc(100% + 8px);' + ' margin-left: 8px;' + ' border-radius: 5px;' + '}' + '' ); // Necessary for autoreconnect window.onbeforeunload = null; const scope = angular.element(document.getElementById('topbar')).scope(); /************************************ * * Global Socket Hook * ************************************/ const globalSocketReady = new Event('globalSocketReady'); io.Socket.prototype.o_emit = io.Socket.prototype.o_emit || io.Socket.prototype.emit; io.Socket.prototype.emit = function (eventName, ...args) { if (!window.socket) { window.socket = this; window.dispatchEvent(globalSocketReady); } window.dispatchEvent(new CustomEvent('socketEmit', { detail: { eventName: eventName, args: [...args] } })); return this.o_emit(eventName, ...args); }; /************************************ * * Autoreconnnect * ************************************/ const disconnectReasons = [ 'transport error', 'transport close', 'io client disconnect', 'io server disconnect', 'ping timeout', ]; const disconnected = JSON.parse(localStorage.getItem('disconnected')); if (disconnected) { localStorage.setItem('disconnected', JSON.stringify(false)); window.addEventListener('globalSocketReady', () => { setTimeout(() => { window.socket.emit('moveAvatar', JSON.parse(localStorage.getItem('avatarPosition'))); }, 1500); }); } window.addEventListener('socketEmit', (event) => { if (event.detail.eventName === 'moveAvatar') { localStorage.setItem('avatarPosition', JSON.stringify(event.detail.args[0])); } if (event.detail.eventName === 'disconnect' && disconnectReasons.includes(event.detail.args[0])) { localStorage.setItem('disconnected', JSON.stringify(true)); location.reload(); } }); /************************************ * * Reload and log Chat History * ************************************/ const maxStoredMessagesPerRoom = 999999; const maxMessageAge = 1000 * 60 * 999999; // 999999 Minutes window.addEventListener('globalSocketReady', () => { window.socket.on('updateChatLines', (data) => { const currentRoom = window.location.href.split('=')[1]; let roomData; if (!localStorage.hasOwnProperty('rooms')) { localStorage.setItem('rooms', JSON.stringify({})); } if (!JSON.parse(localStorage.getItem('rooms')).hasOwnProperty(currentRoom)) { roomData = JSON.parse(localStorage.getItem('rooms')); roomData[currentRoom] = { messages: [], }; roomData = JSON.stringify(roomData); localStorage.setItem('rooms', roomData); } roomData = JSON.parse(localStorage.getItem('rooms')); if (data.user !== 'System') roomData[currentRoom].messages.push(data); if (roomData[currentRoom].messages.length > maxStoredMessagesPerRoom) roomData[currentRoom].messages.splice(0, 1); roomData = JSON.stringify(roomData); localStorage.setItem('rooms', roomData); restoreChatlogs(); }); window.addEventListener('socketEmit', (event) => { if (event.detail.eventName === 'changeRoom') { setTimeout(() => { restoreChatlogs(); }, 100); } }); setInterval(() => { restoreChatlogsWithTimestamp(); }, 240000); // 4 minutes restoreChatlogsWithTimestamp(); }); function restoreChatlogsWithTimestamp() { const currentRoom = window.location.href.split('=')[1]; if (!JSON.parse(localStorage.getItem('rooms')).hasOwnProperty(currentRoom)) { return; } const roomData = JSON.parse(localStorage.getItem('rooms'))[currentRoom]; const currentDate = new Date(); const timestamp = currentDate.getFullYear() + '-' + (currentDate.getMonth() + 1).toString().padStart(2, '0') + '-' + currentDate.getDate().toString().padStart(2, '0') + '-' + currentDate.getHours().toString().padStart(2, '0') + currentDate.getMinutes().toString().padStart(2, '0') + '-'; const blob = new Blob([JSON.stringify(roomData.messages, null, 2)], { type: 'text/plain' }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.setAttribute('href', url); link.setAttribute('download', `${currentRoom}-${timestamp}.txt`); link.style.display = 'none'; document.body.appendChild(link); link.click(); setTimeout(() => { URL.revokeObjectURL(url); document.body.removeChild(link); }, 0); } /************************************ * * Chat Data Collector * ************************************/ if (localStorage.hasOwnProperty('rooms')) { const chatLogs = JSON.parse(localStorage.getItem('rooms')); if (chatLogs) { for (const room in chatLogs) { const tooOldMessages = []; for (const message in chatLogs[room].messages) { if (Date.now() - chatLogs[room].messages[message].timestamp > maxMessageAge) { tooOldMessages.push(message); } } for (const index of tooOldMessages) { chatLogs[room].messages.splice(index, 1); } if (chatLogs[room].messages.length === 0) { delete chatLogs[room]; } } } localStorage.setItem('rooms', JSON.stringify(chatLogs)); } })();