Portado de la extensión de Chrome "Asistente RT ManagerZone". iniciarRT(): inyecta el botón "🔎 Investigar" en la bandeja de request-tracker, parsea el asunto del ticket y abre las solapas de control (bifurca report_cheater vs. transferencias). autocompletarBusquedaPlayer(): en control, autocompleta y envía el buscador cuando llega con action_type=player. Ambas se auto-gatean por hostname. Sin dependencias (no usa jQuery ni ga-core).
بۇ قوليازمىنى بىۋاسىتە قاچىلاشقا بولمايدۇ. بۇ باشقا قوليازمىلارنىڭ ئىشلىتىشى ئۈچۈن تەمىنلەنگەن ئامبار بولۇپ، ئىشلىتىش ئۈچۈن مېتا كۆرسەتمىسىگە قىستۇرىدىغان كود: // @require https://update.greasyfork.org/scripts/588187/1882753/GA%20RT%20%28ManagerZone%29.js
// ==UserScript==
// @name GA RT (ManagerZone)
// @namespace https://control.managerzone.com/ga
// @version 1.1.0
// @description Portado de la extensión de Chrome "Asistente RT ManagerZone", con lupas en 3 puntos: tabla con "Coger" (original), tabla de mayor Prioridad (sin "Coger") y página del ticket (debajo del messagebody). La lógica de parseo/apertura está extraída en rtInvestigar() y el botón en crearLupa(): los tres puntos comparten el MISMO comportamiento. autocompletarBusquedaPlayer() actúa en control. Auto-gateadas por hostname. Sin dependencias.
// ==/UserScript==
(function () {
'use strict';
window.GA = window.GA || {};
const GA = window.GA;
// ==========================================
// PARTE 1: LÓGICA PARA LA BANDEJA DE RT
// ==========================================
GA.iniciarRT = function () {
if (!window.location.hostname.includes("request-tracker")) return;
// ------------------------------------------------------------------
// crearLupa() — EXTRAÍDO del handler original, sin cambios.
// Devuelve el <a> "🔎 Investigar" con el mismo aspecto de siempre.
// ------------------------------------------------------------------
function crearLupa() {
const btnInvestigar = document.createElement('a');
btnInvestigar.innerText = '🔎 Investigar';
btnInvestigar.className = 'mz-investigate-btn';
btnInvestigar.href = '#';
btnInvestigar.style.cursor = 'pointer';
btnInvestigar.style.color = '#487048';
btnInvestigar.style.fontWeight = 'bold';
btnInvestigar.style.textDecoration = 'none';
return btnInvestigar;
}
// ------------------------------------------------------------------
// rtInvestigar(textoAsunto) — EXTRAÍDO del handler original.
// Es el MISMO código que corría dentro del botón: decide si el
// ticket es report_cheater o transferencia y abre las solapas.
// Ahora lo comparten los tres puntos de inyección.
// ------------------------------------------------------------------
function rtInvestigar(textoAsunto) {
// ==========================================
// BIFURCACIÓN: ¿Qué tipo de ticket es?
// ==========================================
if (textoAsunto.includes('report_cheater')) {
// --- CASO 1: REPORT CHEATER ---
const match = textoAsunto.match(/\((\d+)\)/);
if (match && match[1]) {
const userId = match[1];
const searchUrl = `https://control.managerzone.com/?p=ga_admin&sub=searchresult&searchtype=user&searchstr=${userId}&searchtype-reference=user&searchstr-reference=`;
window.open(searchUrl, '_blank');
} else {
alert("GA-Assistant: No se pudo extraer el ID del usuario del ticket report_cheater.");
}
} else {
// --- CASO 2: TRANSFERENCIAS (Tu código original) ---
const deporteMatch = textoAsunto.match(/(soccer|hockey)/i);
const deporte = deporteMatch ? deporteMatch[1].toLowerCase() : "";
const userIdsMatch = textoAsunto.match(/\((\d+)\).*?\((\d+)\)/);
const vendedorId = userIdsMatch ? userIdsMatch[1] : "";
const compradorId = userIdsMatch ? userIdsMatch[2] : "";
const playerIdMatch = textoAsunto.match(/Player ID\s*(\d+)/i);
const playerId = playerIdMatch ? playerIdMatch[1] : "";
if (deporte && vendedorId && compradorId) {
// Pestaña 1: Búsqueda del Jugador en CheatNow
const urlCheatNow = `https://control.managerzone.com/?p=ga_admin&sub=cheatnow&sport=${deporte}&user1=${vendedorId}&user2=${compradorId}&player=${playerId}&action_type=player`;
window.open(urlCheatNow, '_blank');
// Pestaña 2: Ficha del Vendedor con cruce de referencia al Comprador
const urlVendedor = `https://control.managerzone.com/?p=ga_admin&sub=searchresult&searchtype=user&searchstr=${vendedorId}&searchtype-reference=user&searchstr-reference=${compradorId}`;
window.open(urlVendedor, '_blank');
// Pestaña 3: Ficha del Comprador con cruce de referencia al Vendedor
const urlComprador = `https://control.managerzone.com/?p=ga_admin&sub=searchresult&searchtype=user&searchstr=${compradorId}&searchtype-reference=user&searchstr-reference=${vendedorId}`;
window.open(urlComprador, '_blank');
} else {
alert("La estructura del asunto no coincide con el formato esperado. Faltan datos.");
}
}
}
function injectDashboardButtons() {
const takeLinks = document.querySelectorAll('a[href*="Action=Take"]');
takeLinks.forEach(link => {
const parentTd = link.parentElement;
if (parentTd.querySelector('.mz-investigate-btn')) return;
const btnInvestigar = crearLupa();
btnInvestigar.addEventListener('click', (e) => {
e.preventDefault();
const ticketRow = link.closest('tbody.list-item');
const celdas = ticketRow.querySelectorAll('td');
let textoAsunto = "";
if (celdas.length > 1) {
textoAsunto = celdas[1].innerText.trim();
}
rtInvestigar(textoAsunto);
});
link.after(' | ', btnInvestigar);
});
}
// ------------------------------------------------------------------
// injectPrioridadButtons() — NUEVO.
// La tabla "N° | Asunto | Prioridad | Cola | Estado" NO trae link
// "Coger", por eso injectDashboardButtons (que se cuelga de
// a[href*="Action=Take"]) nunca la alcanza. Acá recorremos los
// tbody.list-item que no tienen "Coger" y les colgamos la lupa en
// la celda del Asunto (esa tabla no tiene columna de acciones).
// ------------------------------------------------------------------
function injectPrioridadButtons() {
const filas = document.querySelectorAll('tbody.list-item');
filas.forEach(fila => {
if (fila.querySelector('.mz-investigate-btn')) return;
if (fila.querySelector('a[href*="Action=Take"]')) return;
// La celda del Asunto NO está siempre en el mismo índice:
// vistazo/prioridad -> N° | Asunto | Prioridad | Cola | Estado (índice 1)
// lista lateral -> N° | Propietario | Asunto | Estado (índice 2)
// Por eso se detecta por contexto, no por posición: es la primera
// celda con link al ticket cuyo texto no sean sólo dígitos (la de
// sólo dígitos es la del número de ticket).
let celdaAsunto = null;
fila.querySelectorAll('td').forEach(td => {
if (celdaAsunto) return;
if (!td.querySelector('a[href*="Ticket/Display.html"]')) return;
const t = td.innerText.trim();
if (!t || /^\d+$/.test(t)) return;
celdaAsunto = td;
});
if (!celdaAsunto) return;
// Se lee ANTES de insertar la lupa: como el botón queda dentro
// de esta misma celda, leerlo después ensuciaría el asunto.
const textoAsunto = celdaAsunto.innerText.trim();
if (!textoAsunto) return;
const btnInvestigar = crearLupa();
btnInvestigar.addEventListener('click', (e) => {
e.preventDefault();
rtInvestigar(textoAsunto);
});
celdaAsunto.append(' | ', btnInvestigar);
});
}
// ------------------------------------------------------------------
// injectTicketDisplayButton() — NUEVO.
// En la página del ticket el asunto está en #header h1, con el
// formato "#565574: PL - soccer - koral(2393336) - ...". Se le saca
// el "#nnnnn: " del principio para dejarlo igual que en la tabla.
// La lupa va justo debajo del .messagebody.
// ------------------------------------------------------------------
function injectTicketDisplayButton() {
if (document.getElementById('mz-investigate-ticket')) return;
const cuerpo = document.querySelector('.messagebody');
if (!cuerpo) return;
const h1 = document.querySelector('#header h1');
if (!h1) return;
const textoAsunto = h1.innerText.trim().replace(/^#\d+:\s*/, '');
if (!textoAsunto) return;
const cont = document.createElement('div');
cont.id = 'mz-investigate-ticket';
cont.style.padding = '8px 0';
cont.style.borderTop = '1px solid #ccc';
cont.style.textAlign = 'right';
const btnInvestigar = crearLupa();
btnInvestigar.style.fontSize = '14px';
btnInvestigar.addEventListener('click', (e) => {
e.preventDefault();
rtInvestigar(textoAsunto);
});
cont.appendChild(btnInvestigar);
cuerpo.after(cont);
}
function inyectarTodo() {
injectDashboardButtons();
injectPrioridadButtons();
injectTicketDisplayButton();
}
inyectarTodo();
setInterval(inyectarTodo, 2000);
};
// PARTE 2: LÓGICA PARA LA PÁGINA DE CONTROL
// ==========================================
GA.autocompletarBusquedaPlayer = function () {
if (!window.location.hostname.includes("control.managerzone.com")) return;
const urlParams = new URLSearchParams(window.location.search);
const actionType = urlParams.get('action_type');
const playerId = urlParams.get('player');
if (actionType === 'player' && playerId) {
const cajaTexto = document.querySelector('input[name="search_string"]');
const menuDesplegable = document.querySelector('select[name="search_type"]');
if (cajaTexto && menuDesplegable && cajaTexto.value === "") {
cajaTexto.value = playerId;
menuDesplegable.value = 'player_id';
const formulario = cajaTexto.closest('form');
if (formulario) {
formulario.submit();
} else {
const btnSearch = document.querySelector('input[value="Search"], input[type="submit"]');
if (btnSearch) btnSearch.click();
}
}
}
};
})();