perfectionist-plugins 2.4.3 → 2.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Perfectionism
4
4
 
5
- **Small plugins that fix the annoying parts of League of Legends champ select.**
5
+ **Small plugins that fix the annoying parts of the League of Legends client.**
6
6
 
7
7
  Built for [Pengu Loader](https://pengu.lol)
8
8
 
@@ -16,85 +16,29 @@ Built for [Pengu Loader](https://pengu.lol)
16
16
 
17
17
  ## Plugins
18
18
 
19
- <table>
20
- <tr>
21
- <th align="left">🛡️ Ban Blocker</th>
22
- </tr>
23
- <tr>
24
- <td>
25
- In champ select, every teammate except you gets a <b>BLOCK</b> button.
26
- <br><br>
27
- While a teammate is blocked, the plugin instantly prepicks the champion they are about to ban on your own pick turn. That way, their ban can never land on it.
28
- </td>
29
- </tr>
30
- <tr>
31
- <td>&nbsp;</td>
32
- </tr>
33
- <tr>
34
- <th align="left">🎨 Hide Unowned Skins</th>
35
- </tr>
36
- <tr>
37
- <td>
38
- In champ select, the skin carousel only shows the skins you own for the champion you picked.
39
- <br><br>
40
- The list is filtered where the client reads it, so the carousel, the arrows and the dots all move through owned
41
- skins only, and the ones that are left keep their normal spacing.
42
- </td>
43
- </tr>
44
- <tr>
45
- <td>&nbsp;</td>
46
- </tr>
47
- <tr>
48
- <th align="left">🔓 Unlock Profile Skins</th>
49
- </tr>
50
- <tr>
51
- <td>
52
- In the <b>Set profile background</b> window, every skin shows as unlocked, even the event skins (Signature).
53
- <br><br>
54
- Browse the full list and pick any skin you like as your profile background.
55
- </td>
56
- </tr>
57
- <tr>
58
- <td>&nbsp;</td>
59
- </tr>
60
- <tr>
61
- <th align="left">🎁 Auto Claimer</th>
62
- </tr>
63
- <tr>
64
- <td>
65
- Claims every reward for you the moment it becomes claimable — event tracks, missions and the TFT Battle Pass.
66
- <br><br>
67
- Three optional extras: auto-buy shop items Riot lists for 1 BE, auto-open mystery loot (icons, ward skins), and auto-open chests with keys.
68
- </td>
69
- </tr>
70
- <tr>
71
- <td>&nbsp;</td>
72
- </tr>
73
- <tr>
74
- <th align="left">🚀 BetterClient</th>
75
- </tr>
76
- <tr>
77
- <td>
78
- Debloats the client without changing how it looks or behaves and fixes bugs.
79
- <br><br>
80
- For weaker machines there is one optional switch, <b>Performance mode</b>, which drops background blur,
81
- decorative animation and looping background video. Leave it off and the client is pixel-identical.
82
- </td>
83
- </tr>
84
- </table>
19
+ | Plugin | What it does |
20
+ | --- | --- |
21
+ | 🚀 **BetterClient** | Makes the client lighter and smoother without changing how it looks or behaves. Cuts tracking and repeated requests and fixes small bugs. For weaker PCs there is one optional switch, **Performance mode**, which drops background blur, decorative animation and looping background video. Leave it off and the client is pixel-identical. |
22
+ | 🛡️ **Ban Blocker** | Adds a **BLOCK** button to your teammates in champ select. While a teammate is blocked, the champion they are about to ban is prepicked for you on your own pick turn, so their ban can never land on it. |
23
+ | 🔓 **Unlock Profile Skins** | In the **Set profile background** window, every skin shows as unlocked, even event skins (Signature). Browse the full list and pick any skin you like. |
24
+ | 🎨 **Hide Unowned Skins** | In champ select, the skin carousel only shows the skins you own for the champion you picked. The arrows and dots only move through owned skins, and the ones that are left keep their normal spacing. |
25
+ | ✅ **Auto Accept** | Accepts the match for you when the ready check pops up. Add an optional delay, and switch it on or off from the lobby footer. |
26
+ | 🚪 **Dodge Helper** | Adds a button to leave champ select: **DODGE** in ranked Solo/Duo and Flex, with the estimated LP you will lose, and **QUIT** in every other mode. |
27
+ | 🎁 **Auto Claimer** | Claims rewards for you the moment they become claimable: event tracks, missions and the TFT Battle Pass. Three optional extras: auto-buy shop items Riot lists for 1 BE, auto-open mystery loot (icons, ward skins), and auto-open chests with keys. |
28
+ | 📬 **Auto Read** | Marks quests, loot, Clash, TFT and client notices as read, so no badge or dot stays lit. |
85
29
 
86
30
  ## Install
87
31
 
88
32
  1. Download this repo.
89
33
  2. Move the `Perfectionism` folder into your Pengu Loader `plugins` folder.
90
34
  3. Restart the League Client.
35
+ 4. Open **Settings → Perfectionism** to turn plugins on or off and change their options.
91
36
 
92
37
  ## Updates
93
38
 
94
- Every time the client starts, the loader checks npm for a newer version and runs it. Publishing
95
- a new version of the npm package **is** the update. If a new version appears while the client is
96
- already open, the suite downloads it with a progress window and restarts the client at a safe
97
- moment (never in the middle of a game). You never replace files by hand.
39
+ Perfectionism updates itself. Every time the client starts, the loader checks npm for a newer version and runs it.
40
+ If a new version appears while the client is already open, it downloads it with a progress window and restarts the
41
+ client at a safe moment (never in the middle of a game). You never replace files by hand.
98
42
 
99
43
  <br>
100
44
 
@@ -106,4 +50,4 @@ Made by **Sr. King** 👑
106
50
 
107
51
  If these helped you, a ⭐ on the repo is always nice.
108
52
 
109
- </div>
53
+ </div>
package/auto-accept.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const PLUGIN_ID = "auto-accept";
2
- export const version = "1.1.0";
2
+ export const version = "1.1.2";
3
3
 
4
4
  const PHASE_URI = "/lol-gameflow/v1/gameflow-phase";
5
5
  const READY_CHECK_URI = "/lol-matchmaking/v1/ready-check";
@@ -9,13 +9,18 @@ const DELAY_KEY = "perfectionist:auto-accept:delay";
9
9
  const MAX_DELAY = 15000;
10
10
  const RETRY_MS = 700;
11
11
  const MAX_ATTEMPTS = 4;
12
+ const GAME_SELECT_GUARD_MS = 1500;
12
13
  const STYLE_ID = "perf-auto-accept-style";
13
14
  const ROOT_ID = "perfAutoAccept";
14
15
  const TOGGLE_ID = "perfAutoAcceptToggle";
15
16
  const DELAY_INPUT_ID = "perfAutoAcceptDelay";
16
17
 
17
- const CSS = `#perfAutoAccept { display: flex !important; align-items: center !important; gap: 8px !important; }
18
- #perfAutoAccept .auto-accept-button { cursor: pointer !important; }
18
+ const CSS = `#perfAutoAccept {
19
+ display: flex !important; flex-direction: row !important; flex-wrap: nowrap !important;
20
+ align-items: center !important; gap: 8px !important; width: max-content !important;
21
+ }
22
+ #perfAutoAccept > * { flex: 0 0 auto !important; }
23
+ #perfAutoAccept .auto-accept-button { display: inline-flex !important; align-items: center !important; cursor: pointer !important; }
19
24
  #perfAutoAccept .auto-accept-button-text {
20
25
  font-family: var(--font-body, "LoL Body", Arial, sans-serif) !important;
21
26
  font-size: 12px !important; letter-spacing: 0.3px !important; color: #a09b8c !important;
@@ -23,7 +28,7 @@ const CSS = `#perfAutoAccept { display: flex !important; align-items: center !im
23
28
  #perfAutoAccept .auto-accept-button[selected] .auto-accept-button-text { color: #f0e6d2 !important; }
24
29
  #perfAutoAccept .auto-accept-delay {
25
30
  display: flex !important; align-items: center !important; box-sizing: border-box !important;
26
- width: 82px !important; height: 24px !important; margin-left: 8px !important;
31
+ width: 82px !important; height: 24px !important; margin-left: 0 !important;
27
32
  background: #1e2328 !important; border: 1px solid #785a28 !important; border-radius: 0 !important;
28
33
  transition: border-color 0.15s ease, background-color 0.15s ease !important;
29
34
  }
@@ -239,6 +244,10 @@ function buildButton() {
239
244
  return root;
240
245
  }
241
246
 
247
+ let buttonRetry = null;
248
+ let gameSelectGuardUntil = 0;
249
+ let gameSelectClickHandler = null;
250
+
242
251
  function footer() {
243
252
  return (
244
253
  document.querySelector(".v2-footer-notifications.ember-view") ??
@@ -246,8 +255,32 @@ function footer() {
246
255
  );
247
256
  }
248
257
 
258
+ function gameSelectOpen() {
259
+ if (Date.now() < gameSelectGuardUntil) return true;
260
+ try {
261
+ return !!document.querySelector(".parties-game-select-screen.game-select-show");
262
+ } catch {
263
+ return false;
264
+ }
265
+ }
266
+
267
+ function onGameSelectClick(event) {
268
+ const target = event.target;
269
+ if (!(target instanceof Element)) return;
270
+ if (!target.closest(".parties-game-select-screen, .play-button-container, .lobby-back-button")) return;
271
+ gameSelectGuardUntil = Date.now() + GAME_SELECT_GUARD_MS;
272
+ clearTimeout(buttonRetry);
273
+ buttonRetry = setTimeout(ensureButton, GAME_SELECT_GUARD_MS + 100);
274
+ }
275
+
249
276
  function ensureButton() {
250
277
  if (!active) return;
278
+ clearTimeout(buttonRetry);
279
+ buttonRetry = null;
280
+ if (gameSelectOpen()) {
281
+ buttonRetry = setTimeout(ensureButton, 750);
282
+ return;
283
+ }
251
284
  const host = footer();
252
285
  if (!host) return;
253
286
  if (!document.getElementById(ROOT_ID)) host.append(buildButton());
@@ -270,6 +303,10 @@ function onEnable(utils) {
270
303
  domObserver = new MutationObserver(scheduleEnsure);
271
304
  domObserver.observe(document.documentElement ?? document, { childList: true, subtree: true });
272
305
 
306
+ gameSelectClickHandler = onGameSelectClick;
307
+ document.addEventListener("pointerdown", gameSelectClickHandler, true);
308
+ document.addEventListener("click", gameSelectClickHandler, true);
309
+
273
310
  for (const uri of [PHASE_URI, READY_CHECK_URI]) {
274
311
  try {
275
312
  const off = utils.subscribe(uri, uri === PHASE_URI ? onPhase : onReadyCheck);
@@ -294,6 +331,14 @@ function onDisable() {
294
331
  domObserver = null;
295
332
  clearTimeout(domTimer);
296
333
  domTimer = null;
334
+ clearTimeout(buttonRetry);
335
+ buttonRetry = null;
336
+ if (gameSelectClickHandler) {
337
+ document.removeEventListener("pointerdown", gameSelectClickHandler, true);
338
+ document.removeEventListener("click", gameSelectClickHandler, true);
339
+ }
340
+ gameSelectClickHandler = null;
341
+ gameSelectGuardUntil = 0;
297
342
  document.getElementById(ROOT_ID)?.remove();
298
343
  removeStyle?.();
299
344
  removeStyle = null;
@@ -315,7 +360,6 @@ export function init() {
315
360
  description:
316
361
  "Accepts the ready check automatically, with an optional delay. The same switch is shown natively in the lobby footer.",
317
362
  version,
318
- defaultEnabled: true,
319
363
  options: [
320
364
  {
321
365
  key: OPTION_KEY,
@@ -338,4 +382,4 @@ export function init() {
338
382
  addEventListener("perfectionist:utils-ready", (event) => registerWith(event.detail ?? window.PerfectionistUtils), {
339
383
  once: true,
340
384
  });
341
- }
385
+ }
package/auto-claimer.js CHANGED
@@ -362,7 +362,6 @@ export function init() {
362
362
  name: "Auto Claimer",
363
363
  description: "Automatically claims battle pass, event and mission rewards the moment they become claimable.",
364
364
  version,
365
- defaultEnabled: true,
366
365
  options: [
367
366
  {
368
367
  key: "buy1Be",
@@ -402,4 +401,4 @@ export function init() {
402
401
  return;
403
402
  }
404
403
  addEventListener("perfectionist:utils-ready", (e) => registerWith(e.detail ?? window.PerfectionistUtils), { once: true });
405
- }
404
+ }
package/auto-read.js CHANGED
@@ -358,7 +358,6 @@ export function init() {
358
358
  name: "Auto Read",
359
359
  description: "Automatically marks quests, loot, Clash, TFT and client notices as read so no badge or dot stays lit.",
360
360
  version,
361
- defaultEnabled: true,
362
361
  options: [
363
362
  {
364
363
  type: "chips",
@@ -388,4 +387,4 @@ export function init() {
388
387
  return;
389
388
  }
390
389
  addEventListener("perfectionist:utils-ready", (e) => registerWith(e.detail ?? window.PerfectionistUtils), { once: true });
391
- }
390
+ }
package/ban-blocker.js CHANGED
@@ -632,7 +632,6 @@ export function init() {
632
632
  name: "Ban Blocker",
633
633
  description: "During bans, blocking a teammate instantly claims the champion they hover to ban.",
634
634
  version,
635
- defaultEnabled: true,
636
635
  onEnable,
637
636
  onDisable,
638
637
  });
@@ -647,4 +646,4 @@ export function init() {
647
646
  (e) => registerWith(e.detail ?? window.PerfectionistUtils),
648
647
  { once: true },
649
648
  );
650
- }
649
+ }