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})();