Sku v42.12 - notes de version

La feuille de personnage relit la description de chaque caractéristique

Simple : Sous « Stats », chaque valeur - dégâts des sorts, score de toucher des sorts, endurance, vitesse d'arme et toutes les autres - n'avait que son nom et son chiffre. La description que le jeu affiche à côté était vide : ce que fait la caractéristique, le détail par école de magie, main droite et main gauche. La touche de texte intégral ne disait rien sur ces entrées. Seules les résistances et votre équipement avaient une description. Désormais chaque caractéristique en a une, et elle est relue chaque fois que vous arrivez sur l'entrée, elle est donc à jour après un buff ou un changement d'équipement également.

Technique : La lecture de l'infobulle était mise en commentaire à cet endroit et chaque entrée était construite avec un textFull vide - inchangé depuis la v41.06, ce n'est donc pas la refonte qui l'a cassé, cela n'a jamais fonctionné. Deux raisons pour lesquelles cela ne pouvait pas fonctionner tel qu'écrit : GetButtonTooltipLines était appelé avec GameTooltip comme deuxième argument, ce qui saute précisément l'étape qui remplit l'infobulle ; et sans cet argument l'assistant aurait quand même abandonné, car il ne déclenche un OnEnter que pour les objets portant un marqueur .type - les cadres de caractéristiques n'en ont pas, ce qui est exactement pourquoi la boucle des résistances le pose avant sa propre lecture. S'y ajoutait une troisième raison, celle qui aurait rendu un correctif naïf faux : TBC fait passer les 29 caractéristiques par UN SEUL widget partagé (PlayerStatFrameLeft1), et les setters de Blizzard y laissent leur état - .tooltip/.tooltip2 ainsi que .bonusDamage/.spellCrit/.damage pour les quatre caractéristiques qui installent leur propre OnEnter. Aucun d'eux n'efface ce que le précédent a laissé, quatre d'entre eux remplacent OnEnter sans jamais le remettre ; le propre UpdatePaperdollStats de Blizzard le repointe avant chaque groupe pour exactement cette raison. Sans la même remise à zéro, la caractéristique N aurait lu la description de la caractéristique N-1. La lecture réinitialise maintenant le widget avant chaque setter et parcourt l'infobulle via NumLines/GameTooltipTextLeft|Right plutôt que GetRegions - ce dernier rend la colonne de gauche et celle de droite comme deux séries distinctes, si bien que le détail par école de magie aurait été lu comme six noms d'école suivis de six chiffres. Le getter dynamique qui relit la valeur à chaque arrivée renvoie désormais la description comme deuxième valeur à côté d'elle, et le widget est ensuite rendu à l'état que Blizzard attend via PaperDollFrame_UpdateStats.

Sku ne dépend plus du fait que des jetons internes restent non traduits

Simple : Sur un client français, la touche du journal de quêtes ne faisait absolument rien - pas de focus, pas de son, pas d'erreur. Un seul mot traduit dans le fichier de localisation française en était la cause. Certaines entrées de ce fichier ne sont pas un libellé mais un jeton interne que Sku utilise pour construire et reconnaître ses propres chemins de menu ; traduisez-en un et l'addon ne retrouve plus son propre chemin. C'est corrigé, et corrigé d'une manière qui ne peut pas se reproduire : le jeton n'est plus un texte traduisible. Si vous avez pris l'habitude de taper un chemin en français, il vous mène toujours au bon endroit. Une deuxième trouvaille du même genre aurait fait basculer silencieusement tous les clients français vers les noms anglais des créatures, des objets et des quêtes à la prochaine remise en ordre du fichier de localisation - cela aussi a disparu.

Technique : Trouvé, diagnostiqué et corrigé par ZenqFR (Games-Access) sur un vrai client français, sous la forme de la PR #2 de ce dépôt. Les modifications qui suivent s'appuient dessus. L["short"] portait deux sens sans rapport : dans environ 25 endroits c'était le premier champ d'un chemin SkuOptions:SlashFunc, c'est-à-dire un jeton de protocole que le code compare avec lui-même, et dans exactement un endroit (SkuCore/aq.lua) c'est un véritable texte destiné à l'utilisateur. Un traducteur ne voit jamais que le second sens. Les deux sont désormais séparés : Sku.MENU_ROOT est le jeton, utilisé par les 23 endroits qui construisent des chemins ainsi que par les six qui codaient en dur le littéral "short," - dont la touche du journal de quêtes. La comparaison accepte toujours L["short"] également, de sorte qu'un chemin localisé que quelqu'un a appris continue de fonctionner. Corrigé au passage : le repli dans

SkuCore/dungeonBrowser.lua était "sku", ce qui n'était pas un jeton valide du tout. Deuxièmement, frFR.lua définissait L["locale"] deux fois - "enUS" dans le corps trié et "frFR" ajouté à la fin. Cela ne se résolvait correctement que grâce à l'ordre d'AceLocale : une locale non par défaut est enregistrée via un proxy qui fait un rawset inconditionnel, donc la DERNIÈRE affectation gagne.

Sku.Loc est lu directement depuis cette clé, et elle détermine quelles tables de noms SkuDB tout le client utilise - régénérer ou trier le fichier aurait fait basculer silencieusement tous les clients français vers les DONNÉES anglaises :

pas d'erreur, pas de ligne de journal, juste les mauvais noms partout. La ligne perdante est supprimée, la survivante documentée, et dev/rework-docs/_locale_dupes.py signale désormais les clés en double par fichier de locale. Ce lint rend aussi visible qu'enUS, en tant que locale par défaut d'AceLocale, fonctionne au contraire en PREMIER-gagnant : la même clé dupliquée peut se résoudre en entrées différentes selon la langue. 64 conflits de ce type existent aujourd'hui, presque tous du bruit de traducteurs anciens ;

ils ont été délibérément laissés en l'état et sont au moins visibles maintenant.

Troisièmement, SkuDBEnsureActiveLocaleTables tient enfin sa promesse - il s'exécute aussi à ADDON_LOADED (auparavant seulement un OnUpdate après PLAYER_LOGIN, si bien que tout ce qui touchait à [Sku.Loc] dans son propre gestionnaire PLAYER_LOGIN voyait nil un instant) et ne retourne plus silencieusement sur un Sku.Loc inutilisable : il valide, journalise le coupable probable, et construit les tables quoi qu'il arrive.

La parole ne se tait plus quand vous parcourez une liste rapidement

Simple : Faire défiler rapidement un menu, une liste d'objets proches ou vos sacs pouvait couper la parole entièrement - il ne restait que les sons de clic et de balise - jusqu'à ce que vous attendiez quelques secondes ou que vous alliez dans une autre partie de l'interface. Chaque entrée devant laquelle vous passiez était avalée, et souvent aussi celle sur laquelle vous vous arrêtiez finalement. Désormais chaque entrée survolée est remise à la voix, et l'entrée sur laquelle vous vous arrêtez est prononcée. Rien n'a changé quant à l'annonce qui l'emporte : une nouvelle remplace toujours la précédente, un défilement rapide ne lit donc toujours que ce sur quoi vous vous arrêtez, et l'interruption de la parole en combat est inchangée.

Technique : La pompe TTS de Blizzard se cadençait avec un compte à rebours qui soustrayait un seul delta d'image par exécution, mais son corps ne s'exécute que toutes les 0,01 s - donc au-dessus d'environ 100 images par seconde elle soustrayait bien moins que le temps réellement écoulé, et la pause de 0,1 s prévue avant l'énoncé suivant s'étirait à 0,2-0,3 s réelles. Comme une réinitialisation de file supprime la ligne qui attend encore, une pause plus longue signifiait plus d'annonces perdues : le bug empirait à mesure que la fréquence d'images montait. La pause est maintenant une échéance GetTime, identique à 60 ips et correcte au-dessus. Mesuré sur une capture à 6-7 appuis de touche par seconde : avant, 7 réinitialisations produisaient 2 lignes prononcées ; après, 7 réinitialisations en produisent 7. Une seconde protection supprime un StopSpeakingText quand rien n'est en vol et qu'un autre a déjà été envoyé dans les 0,15 s - le client traite les arrêts de façon asynchrone, si bien qu'un arrêt tardif pouvait annuler l'énoncé suivant avant qu'il ne commence. Cette protection ne se déclenche plus jamais pendant la navigation ; elle demeure pour les rafales événementielles (courrier, discussion) qui produisaient 17 arrêts en une seconde sans aucune parole.

Moins de travail par ligne prononcée

Simple : Sku effectue nettement moins de travail pour chaque ligne qu'il prononce et chaque son qu'il joue, ce qui se traduit par un défilement plus fluide.

Technique : Deux diagnostics temporaires [SOUND-PROBE] ont été supprimés. Tous deux passaient debugstack(...) en argument à dprint, et dprint ne teste l'indicateur de débogage qu'à l'intérieur de lui-même - un parcours complet de la pile s'exécutait donc pour chaque son même avec la journalisation désactivée, et celui de Sku/Core.lua accrochait le PlaySound global, si bien que les propres appels de Blizzard le payaient aussi. Ils représentaient un quart de toutes les lignes de journal capturées. La pompe de file saute désormais entièrement ses balayages tant que les deux files sont vides, au lieu de les exécuter une centaine de fois par seconde, et la recherche de lien wiki abandonne avant de normaliser la chaîne plutôt qu'après : elle est appelée pour chaque ligne prononcée depuis OutputStringBTtts, où son résultat est de toute façon jeté, et sans index wiki elle effectuait environ 19 passes de string.gsub pour atteindre une garde qui ne faisait rien.

L'installateur et la page de téléchargement parlent français eux aussi

Simple : Sku lui-même parle français depuis la v42.11, mais tout ce qui l'entoure non. Le Sku Installer fonctionne désormais en français - il prend sa langue de Windows, et vous pouvez la changer à tout moment dans la liste « Langue de cet installateur » - et la page de téléchargement existe en version française, accessible par les liens de langue en haut de chaque page. Ces notes de version existent elles aussi en français, à partir de la v42.11. Il n'y a toujours pas de pack de voix français : sur un client français, Sku parle par votre lecteur d'écran, et c'est pourquoi l'installateur y propose le pack anglais. L'installateur passe ainsi en version 4.1.

Technique : Une table française dans le Loc.cs de l'installateur (Lang.Fr, le même jeu de clés que l'anglais et l'allemand, « fr » repris de la culture d'interface du système ; la liste des langues est construite à partir de ComponentsForm._langOrder, plus aucun littéral d'index à maintenir), docs/index-fr.html, et « Patch Notes Sku FR.txt » que release.ps1 recopie sur le site. Les réécritures de la page dans release.ps1 parcourent maintenant une LISTE de pages et s'appuient sur des fragments neutres du point de vue de la langue, pour qu'une page traduite ne puisse pas conserver un numéro de version périmé - exactement la panne corrigée pour le titre en v42.11, une page plus loin ; au passage, le titre de SkuMapper est couvert lui aussi, alors qu'il dérivait sans que personne le remarque. L'annonce Discord se fait désormais par canal : une ligne de webhook peut nommer les langues de ce canal, un serveur uniquement germanophone reçoit donc une seule ligne allemande avec des liens allemands, au lieu de trois langues qu'il n'a pas demandées.

Deux menus qui n'étaient qu'un détour ont disparu

Simple : Sous « Réglages » se trouvait une entrée « Combat » qui ne contenait qu'un seul élément : « Menu Sku en combat ». Cet élément se trouve désormais directement dans « Réglages, Général », et le niveau « Combat » vide au-dessus n'existe plus. Même chose dans le menu principal : « Outils » ne contenait que « Dial Targeting » et « Soft Targeting » ; les deux sont maintenant dans le « Menu rapide », et « Outils » a quitté le menu principal. Les réglages eux-mêmes ne changent pas, et toutes les valeurs déjà enregistrées sont conservées.

Technique : Les trois entrées gardent leurs builders, leur db et leur keyPrefix - seul l'endroit où elles sont accrochées change, les valeurs enregistrées sont donc intactes. « Werkzeuge » est retiré comme module SkuMenu et de SkuMenu:SetRootLayout (SkuZOptions/SkuMenu.lua) ; DialTargetingMenuBuilder et le groupe softTargeting (toujours via IterateOptionsArgs avec

aIncludeHidden=true, puisqu'il est marqué forAudioMenu=false) sont désormais accrochés dans le BuildChildren du menu rapide (SkuZOptions/Core.lua). La spécification « Kampf » sort de tSpecs dans SkuCore/Options.lua ;

CombatMenuOpenMenuBuilder est maintenant appelé à la fin du builder Général, sur le même réglage combatMenuOpen. Aucun chemin SlashFunc ne pointait vers l'un de ces deux menus, il n'y avait donc rien d'autre à suivre.