Progrentis Points Modifier

A new extension

Size

19.7 KB

Version

1.1.3

Created

Nov 10, 2025

Updated

about 1 month ago

1// ==UserScript==
2// @name		Progrentis Points Modifier
3// @description		A new extension
4// @version		1.1.3
5// @match		https://*.prod.progrentis.com/*
6// @icon		https://prod.progrentis.com/Portals/6/favicon.ico
7// ==/UserScript==
8(function() {
9    'use strict';
10
11    console.log('Progrentis Points Modifier iniciado');
12
13    let modifiedPoints = null;
14
15    // Función para obtener los puntos modificados guardados
16    async function getSavedPoints() {
17        const saved = await GM.getValue('progrentis_points', null);
18        console.log('Puntos guardados recuperados:', saved);
19        return saved;
20    }
21
22    // Función para guardar los puntos modificados
23    async function savePoints(points) {
24        await GM.setValue('progrentis_points', points);
25        console.log('Puntos guardados:', points);
26    }
27
28    // Función para obtener la unidad guardada
29    async function getSavedUnit() {
30        const saved = await GM.getValue('progrentis_unit', null);
31        console.log('Unidad guardada recuperada:', saved);
32        return saved;
33    }
34
35    // Función para guardar la unidad
36    async function saveUnit(unit) {
37        await GM.setValue('progrentis_unit', unit);
38        console.log('Unidad guardada:', unit);
39    }
40
41    // Función para obtener el estado de objetivos desbloqueados
42    async function getSavedUnlockState() {
43        const saved = await GM.getValue('progrentis_unlocked', false);
44        console.log('Estado de desbloqueo recuperado:', saved);
45        return saved;
46    }
47
48    // Función para guardar el estado de objetivos desbloqueados
49    async function saveUnlockState(unlocked) {
50        await GM.setValue('progrentis_unlocked', unlocked);
51        console.log('Estado de desbloqueo guardado:', unlocked);
52    }
53
54    // Función para aplicar los puntos modificados
55    async function applyModifiedPoints() {
56        const savedPoints = await getSavedPoints();
57        if (savedPoints !== null) {
58            modifiedPoints = savedPoints;
59            const pointsDisplay = document.querySelector('div[data-v-811803be].points span.big');
60            if (pointsDisplay) {
61                pointsDisplay.textContent = savedPoints.toString();
62                console.log('Puntos aplicados desde almacenamiento:', savedPoints);
63            }
64        }
65    }
66
67    // Función para aplicar la unidad guardada
68    async function applyModifiedUnit() {
69        const savedUnit = await getSavedUnit();
70        if (savedUnit !== null) {
71            const unitDisplay = document.querySelector('div[data-v-3c5bfa5d].unidad');
72            if (unitDisplay) {
73                unitDisplay.textContent = `UNIDAD ${savedUnit}`;
74                console.log('Unidad aplicada desde almacenamiento:', savedUnit);
75            }
76        }
77    }
78
79    // Función para aplicar el desbloqueo de objetivos
80    async function applyUnlockedObjectives() {
81        const isUnlocked = await getSavedUnlockState();
82        if (isUnlocked) {
83            const objectives = document.querySelectorAll('div[data-un-premio][data-disabled="true"]');
84            objectives.forEach((objective, index) => {
85                objective.removeAttribute('data-disabled');
86                objective.setAttribute('data-disabled', 'false');
87                objective.style.opacity = '1';
88                objective.style.filter = 'none';
89                objective.style.pointerEvents = 'auto';
90                objective.style.cursor = 'pointer';
91            });
92            console.log('Objetivos desbloqueados aplicados desde almacenamiento');
93        }
94    }
95
96    // Función para desbloquear todos los objetivos
97    async function unlockAllObjectives() {
98        const objectives = document.querySelectorAll('div[data-un-premio][data-disabled="true"]');
99        console.log('Objetivos encontrados:', objectives.length);
100        
101        objectives.forEach((objective, index) => {
102            objective.removeAttribute('data-disabled');
103            objective.setAttribute('data-disabled', 'false');
104            // Cambiar estilo visual para que se vea desbloqueado
105            objective.style.opacity = '1';
106            objective.style.filter = 'none';
107            objective.style.pointerEvents = 'auto';
108            objective.style.cursor = 'pointer';
109            console.log(`Objetivo ${index + 1} desbloqueado`);
110        });
111
112        if (objectives.length > 0) {
113            await saveUnlockState(true);
114            showSuccessMessage(`🎉 ${objectives.length} objetivos desbloqueados`);
115        } else {
116            // Si no hay objetivos bloqueados, verificar si ya están todos desbloqueados
117            const allObjectives = document.querySelectorAll('div[data-un-premio]');
118            if (allObjectives.length > 0) {
119                await saveUnlockState(true);
120                showSuccessMessage('✅ Todos los objetivos ya están desbloqueados');
121            } else {
122                alert('No se encontraron objetivos');
123            }
124        }
125    }
126
127    // Observador para detectar cambios en los puntos y reemplazarlos
128    function observePointsChanges() {
129        const pointsDisplay = document.querySelector('div[data-v-811803be].points span.big');
130        
131        if (!pointsDisplay) {
132            return;
133        }
134
135        const observer = new MutationObserver(async (mutations) => {
136            const savedPoints = await getSavedPoints();
137            if (savedPoints !== null && pointsDisplay.textContent !== savedPoints.toString()) {
138                console.log('Detectado cambio en puntos, restaurando a:', savedPoints);
139                pointsDisplay.textContent = savedPoints.toString();
140            }
141        });
142
143        observer.observe(pointsDisplay, {
144            childList: true,
145            characterData: true,
146            subtree: true
147        });
148
149        console.log('Observer de puntos activado');
150    }
151
152    // Observador para detectar cambios en la unidad y reemplazarla
153    function observeUnitChanges() {
154        const unitDisplay = document.querySelector('div[data-v-3c5bfa5d].unidad');
155        
156        if (!unitDisplay) {
157            return;
158        }
159
160        const observer = new MutationObserver(async (mutations) => {
161            const savedUnit = await getSavedUnit();
162            if (savedUnit !== null && !unitDisplay.textContent.includes(`UNIDAD ${savedUnit}`)) {
163                console.log('Detectado cambio en unidad, restaurando a:', savedUnit);
164                unitDisplay.textContent = `UNIDAD ${savedUnit}`;
165            }
166        });
167
168        observer.observe(unitDisplay, {
169            childList: true,
170            characterData: true,
171            subtree: true
172        });
173
174        console.log('Observer de unidad activado');
175    }
176
177    // Observador para detectar cambios en los objetivos y mantenerlos desbloqueados
178    function observeObjectivesChanges() {
179        const awardsSection = document.querySelector('div[data-seccion-retos-x]');
180        
181        if (!awardsSection) {
182            return;
183        }
184
185        const observer = new MutationObserver(async (mutations) => {
186            const isUnlocked = await getSavedUnlockState();
187            if (isUnlocked) {
188                const objectives = document.querySelectorAll('div[data-un-premio][data-disabled="true"]');
189                if (objectives.length > 0) {
190                    console.log('Detectados objetivos bloqueados, desbloqueando...');
191                    objectives.forEach((objective) => {
192                        objective.removeAttribute('data-disabled');
193                        objective.setAttribute('data-disabled', 'false');
194                        objective.style.opacity = '1';
195                        objective.style.filter = 'none';
196                        objective.style.pointerEvents = 'auto';
197                        objective.style.cursor = 'pointer';
198                    });
199                }
200            }
201        });
202
203        observer.observe(awardsSection, {
204            childList: true,
205            subtree: true,
206            attributes: true,
207            attributeFilter: ['data-disabled']
208        });
209
210        console.log('Observer de objetivos activado');
211    }
212
213    // Función para crear el botón de modificación de puntos
214    function createPointsModifierButton() {
215        const pointsSection = document.querySelector('div[data-v-811803be].points');
216        
217        if (!pointsSection) {
218            console.log('No se encontró la sección de puntos, reintentando...');
219            return false;
220        }
221
222        if (document.getElementById('points-modifier-btn')) {
223            console.log('El botón ya existe');
224            return true;
225        }
226
227        console.log('Creando botón de modificación de puntos');
228
229        const buttonContainer = document.createElement('div');
230        buttonContainer.id = 'points-modifier-container';
231        buttonContainer.style.cssText = `
232            margin-top: 25px;
233            display: flex;
234            flex-direction: column;
235            gap: 10px;
236            align-items: center;
237            justify-content: center;
238            padding-top: 15px;
239            border-top: 2px solid rgba(255, 255, 255, 0.2);
240        `;
241
242        // Primera fila de botones
243        const firstRow = document.createElement('div');
244        firstRow.style.cssText = `
245            display: flex;
246            flex-direction: row;
247            gap: 10px;
248            align-items: center;
249            justify-content: center;
250        `;
251
252        // Botón para modificar puntos
253        const modifyButton = document.createElement('button');
254        modifyButton.id = 'points-modifier-btn';
255        modifyButton.textContent = '✨ Modificar Puntos';
256        modifyButton.style.cssText = `
257            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
258            color: white;
259            border: none;
260            padding: 10px 20px;
261            border-radius: 25px;
262            font-size: 13px;
263            font-weight: bold;
264            cursor: pointer;
265            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
266            transition: all 0.3s ease;
267        `;
268
269        modifyButton.addEventListener('mouseenter', () => {
270            modifyButton.style.transform = 'translateY(-2px)';
271            modifyButton.style.boxShadow = '0 6px 20px rgba(102, 126, 234, 0.6)';
272        });
273
274        modifyButton.addEventListener('mouseleave', () => {
275            modifyButton.style.transform = 'translateY(0)';
276            modifyButton.style.boxShadow = '0 4px 15px rgba(102, 126, 234, 0.4)';
277        });
278
279        modifyButton.addEventListener('click', async () => {
280            const currentPoints = await getSavedPoints() || '0';
281            const newPoints = prompt('¿Cuántos puntos quieres tener?', currentPoints);
282            
283            if (newPoints === null) {
284                return;
285            }
286
287            const pointsValue = parseInt(newPoints);
288            
289            if (isNaN(pointsValue) || pointsValue < 0) {
290                alert('Por favor, ingresa un número válido de puntos (mayor o igual a 0)');
291                return;
292            }
293
294            await savePoints(pointsValue);
295            modifiedPoints = pointsValue;
296
297            const pointsDisplay = document.querySelector('div[data-v-811803be].points span.big');
298            
299            if (pointsDisplay) {
300                pointsDisplay.textContent = pointsValue.toString();
301                console.log(`Puntos modificados a: ${pointsValue}`);
302                showSuccessMessage(`✅ Puntos: ${pointsValue}`);
303            } else {
304                console.error('No se pudo encontrar el elemento de puntos');
305                alert('Error: No se pudo modificar los puntos');
306            }
307        });
308
309        // Botón para resetear puntos
310        const resetButton = document.createElement('button');
311        resetButton.id = 'points-reset-btn';
312        resetButton.textContent = '🔄 Resetear';
313        resetButton.style.cssText = `
314            background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
315            color: white;
316            border: none;
317            padding: 10px 20px;
318            border-radius: 25px;
319            font-size: 13px;
320            font-weight: bold;
321            cursor: pointer;
322            box-shadow: 0 4px 15px rgba(245, 87, 108, 0.4);
323            transition: all 0.3s ease;
324        `;
325
326        resetButton.addEventListener('mouseenter', () => {
327            resetButton.style.transform = 'translateY(-2px)';
328            resetButton.style.boxShadow = '0 6px 20px rgba(245, 87, 108, 0.6)';
329        });
330
331        resetButton.addEventListener('mouseleave', () => {
332            resetButton.style.transform = 'translateY(0)';
333            resetButton.style.boxShadow = '0 4px 15px rgba(245, 87, 108, 0.4)';
334        });
335
336        resetButton.addEventListener('click', async () => {
337            if (confirm('¿Estás seguro de que quieres resetear TODO a los valores originales?')) {
338                await GM.deleteValue('progrentis_points');
339                await GM.deleteValue('progrentis_unit');
340                await GM.deleteValue('progrentis_unlocked');
341                modifiedPoints = null;
342                location.reload();
343            }
344        });
345
346        // Segunda fila de botones
347        const secondRow = document.createElement('div');
348        secondRow.style.cssText = `
349            display: flex;
350            flex-direction: row;
351            gap: 10px;
352            align-items: center;
353            justify-content: center;
354        `;
355
356        // Botón para cambiar de unidad
357        const unitButton = document.createElement('button');
358        unitButton.id = 'unit-changer-btn';
359        unitButton.textContent = '📚 Cambiar Unidad';
360        unitButton.style.cssText = `
361            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
362            color: white;
363            border: none;
364            padding: 10px 20px;
365            border-radius: 25px;
366            font-size: 13px;
367            font-weight: bold;
368            cursor: pointer;
369            box-shadow: 0 4px 15px rgba(79, 172, 254, 0.4);
370            transition: all 0.3s ease;
371        `;
372
373        unitButton.addEventListener('mouseenter', () => {
374            unitButton.style.transform = 'translateY(-2px)';
375            unitButton.style.boxShadow = '0 6px 20px rgba(79, 172, 254, 0.6)';
376        });
377
378        unitButton.addEventListener('mouseleave', () => {
379            unitButton.style.transform = 'translateY(0)';
380            unitButton.style.boxShadow = '0 4px 15px rgba(79, 172, 254, 0.4)';
381        });
382
383        unitButton.addEventListener('click', async () => {
384            const currentUnit = await getSavedUnit() || '1';
385            const unitNumber = prompt('¿A qué unidad quieres ir? (Ejemplo: 1, 2, 3...)', currentUnit);
386            
387            if (unitNumber === null) {
388                return;
389            }
390
391            const unit = parseInt(unitNumber);
392            
393            if (isNaN(unit) || unit < 1) {
394                alert('Por favor, ingresa un número de unidad válido (mayor a 0)');
395                return;
396            }
397
398            await saveUnit(unit);
399
400            // Buscar el elemento de unidad actual
401            const unitDisplay = document.querySelector('div[data-v-3c5bfa5d].unidad');
402            
403            if (unitDisplay) {
404                unitDisplay.textContent = `UNIDAD ${unit}`;
405                console.log(`Unidad cambiada a: ${unit}`);
406                showSuccessMessage(`📚 Cambiado a Unidad ${unit}`);
407            } else {
408                console.error('No se pudo encontrar el elemento de unidad');
409                alert('Error: No se pudo cambiar la unidad');
410            }
411        });
412
413        // Botón para desbloquear objetivos
414        const unlockButton = document.createElement('button');
415        unlockButton.id = 'unlock-objectives-btn';
416        unlockButton.textContent = '🏆 Desbloquear Todo';
417        unlockButton.style.cssText = `
418            background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
419            color: white;
420            border: none;
421            padding: 10px 20px;
422            border-radius: 25px;
423            font-size: 13px;
424            font-weight: bold;
425            cursor: pointer;
426            box-shadow: 0 4px 15px rgba(250, 112, 154, 0.4);
427            transition: all 0.3s ease;
428        `;
429
430        unlockButton.addEventListener('mouseenter', () => {
431            unlockButton.style.transform = 'translateY(-2px)';
432            unlockButton.style.boxShadow = '0 6px 20px rgba(250, 112, 154, 0.6)';
433        });
434
435        unlockButton.addEventListener('mouseleave', () => {
436            unlockButton.style.transform = 'translateY(0)';
437            unlockButton.style.boxShadow = '0 4px 15px rgba(250, 112, 154, 0.4)';
438        });
439
440        unlockButton.addEventListener('click', () => {
441            unlockAllObjectives();
442        });
443
444        firstRow.appendChild(modifyButton);
445        firstRow.appendChild(resetButton);
446        secondRow.appendChild(unitButton);
447        secondRow.appendChild(unlockButton);
448        
449        buttonContainer.appendChild(firstRow);
450        buttonContainer.appendChild(secondRow);
451        pointsSection.appendChild(buttonContainer);
452
453        console.log('Botones creados exitosamente');
454        return true;
455    }
456
457    function showSuccessMessage(text) {
458        const message = document.createElement('div');
459        message.style.cssText = `
460            position: fixed;
461            top: 20px;
462            right: 20px;
463            background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);
464            color: white;
465            padding: 15px 25px;
466            border-radius: 10px;
467            font-weight: bold;
468            box-shadow: 0 4px 15px rgba(17, 153, 142, 0.4);
469            z-index: 10000;
470            animation: slideIn 0.3s ease;
471        `;
472        message.textContent = text;
473
474        document.body.appendChild(message);
475
476        setTimeout(() => {
477            message.style.animation = 'slideOut 0.3s ease';
478            setTimeout(() => message.remove(), 300);
479        }, 3000);
480    }
481
482    const style = document.createElement('style');
483    style.textContent = `
484        @keyframes slideIn {
485            from {
486                transform: translateX(400px);
487                opacity: 0;
488            }
489            to {
490                transform: translateX(0);
491                opacity: 1;
492            }
493        }
494        @keyframes slideOut {
495            from {
496                transform: translateX(0);
497                opacity: 1;
498            }
499            to {
500                transform: translateX(400px);
501                opacity: 0;
502            }
503        }
504    `;
505    document.head.appendChild(style);
506
507    async function init() {
508        console.log('Iniciando creación del botón...');
509        
510        // Aplicar puntos guardados primero
511        await applyModifiedPoints();
512        await applyModifiedUnit();
513        await applyUnlockedObjectives();
514        
515        if (createPointsModifierButton()) {
516            observePointsChanges();
517            observeUnitChanges();
518            observeObjectivesChanges();
519            return;
520        }
521
522        const observer = new MutationObserver(async (mutations, obs) => {
523            if (createPointsModifierButton()) {
524                await applyModifiedPoints();
525                await applyModifiedUnit();
526                await applyUnlockedObjectives();
527                observePointsChanges();
528                observeUnitChanges();
529                observeObjectivesChanges();
530                obs.disconnect();
531            }
532        });
533
534        observer.observe(document.body, {
535            childList: true,
536            subtree: true
537        });
538
539        setTimeout(() => {
540            observer.disconnect();
541            createPointsModifierButton();
542            applyModifiedPoints();
543            applyModifiedUnit();
544            applyUnlockedObjectives();
545            observePointsChanges();
546            observeUnitChanges();
547            observeObjectivesChanges();
548        }, 10000);
549    }
550
551    if (document.readyState === 'loading') {
552        document.addEventListener('DOMContentLoaded', init);
553    } else {
554        init();
555    }
556
557})();
Progrentis Points Modifier | Robomonkey