From 6558792e73fd6f511a2dad0de4e6b17d9634d5e5 Mon Sep 17 00:00:00 2001 From: Przemek Pawlas <3606072+Destroy666x@users.noreply.github.com> Date: Tue, 3 Oct 2023 14:09:29 +0200 Subject: [PATCH] Add Twitch send chat announcement and emote-only mode actions (#890) --- data/locale/en-US.ini | 19 +- data/locale/fr-FR.ini | 69 ++++--- .../twitch/macro-action-twitch.cpp | 175 ++++++++++++++++-- .../twitch/macro-action-twitch.hpp | 32 +++- src/macro-external/twitch/token.cpp | 7 +- 5 files changed, 241 insertions(+), 61 deletions(-) diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 0ccdc787..42c2fdae 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -783,12 +783,21 @@ AdvSceneSwitcher.action.twitch.type.category="Set stream category" AdvSceneSwitcher.action.twitch.type.marker="Create stream marker" AdvSceneSwitcher.action.twitch.type.clip="Create stream clip" AdvSceneSwitcher.action.twitch.type.commercial="Start commercial with duration" +AdvSceneSwitcher.action.twitch.type.announcement="Send chat announcement" +AdvSceneSwitcher.action.twitch.type.emoteOnlyEnable="Enable chat's emote-only mode" +AdvSceneSwitcher.action.twitch.type.emoteOnlyDisable="Disable chat's emote-only mode" AdvSceneSwitcher.action.twitch.categorySelectionDisabled="Cannot select category without selecting a Twitch account first!" -AdvSceneSwitcher.action.twitch.entry="On{{account}}{{actions}}{{streamTitle}}{{category}}{{manualCategorySearch}}{{markerDescription}}{{clipHasDelay}}{{duration}}" +AdvSceneSwitcher.action.twitch.entry.line1="On{{account}}{{actions}}{{streamTitle}}{{category}}{{manualCategorySearch}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}" AdvSceneSwitcher.action.twitch.tokenPermissionsInsufficient="Permissions of selected token are insufficient to perform selected action!" -AdvSceneSwitcher.action.twitch.clip.hasDelay="Add a slight delay before capturing the clip" -AdvSceneSwitcher.action.twitch.marker.description="Describe marker" AdvSceneSwitcher.action.twitch.title.title="Enter title" +AdvSceneSwitcher.action.twitch.marker.description="Describe marker" +AdvSceneSwitcher.action.twitch.clip.hasDelay="Add a slight delay before capturing the clip" +AdvSceneSwitcher.action.twitch.announcement.message="Enter message" +AdvSceneSwitcher.action.twitch.announcement.primary="Primary (channel's accent color)" +AdvSceneSwitcher.action.twitch.announcement.blue="Blue" +AdvSceneSwitcher.action.twitch.announcement.green="Green" +AdvSceneSwitcher.action.twitch.announcement.orange="Orange" +AdvSceneSwitcher.action.twitch.announcement.purple="Purple" ; Hotkey AdvSceneSwitcher.hotkey.startSwitcherHotkey="Start the Advanced Scene Switcher" @@ -943,7 +952,9 @@ AdvSceneSwitcher.twitchToken.analytics.readGames="View analytics data for the ga AdvSceneSwitcher.twitchToken.bits.read="View Bits information for a channel." AdvSceneSwitcher.twitchToken.channel.manageBroadcast="Manage a channel’s broadcast configuration, including updating channel configuration and managing stream markers and stream tags." AdvSceneSwitcher.twitchToken.channel.startCommercial="Run commercials on a channel." -AdvSceneSwitcher.twitchToken.channel.createClip="Create clips from channel's broadcasts." +AdvSceneSwitcher.twitchToken.clips.edit="Create clips from channel's broadcasts." +AdvSceneSwitcher.twitchToken.moderator.manageAnnouncements="Manage channel's chat announcements." +AdvSceneSwitcher.twitchToken.moderator.manageChatSettings="Manage channel's chat settings, such as emote-only or slow mode." AdvSceneSwitcher.twitchCategories.fetchStart="Fetching stream categories ..." AdvSceneSwitcher.twitchCategories.fetchStatus="Got %1 stream categories." diff --git a/data/locale/fr-FR.ini b/data/locale/fr-FR.ini index 061a614a..2d3ae40d 100644 --- a/data/locale/fr-FR.ini +++ b/data/locale/fr-FR.ini @@ -355,7 +355,7 @@ AdvSceneSwitcher.condition.hotkey="Raccourci clavier" AdvSceneSwitcher.condition.hotkey.name="Raccourci clavier de déclenchement de macro" AdvSceneSwitcher.condition.hotkey.tip="Remarque : Vous pouvez configurer les raccourcis clavier pour ce raccourci dans la fenêtre de paramètres d'OBS" AdvSceneSwitcher.condition.hotkey.entry.line1="Raccourci clavier est enfoncé" -AdvSceneSwitcher.condition.hotkey.entry.line2="Nom : {{name}}" +AdvSceneSwitcher.condition.hotkey.entry.line2="Nom :{{name}}" AdvSceneSwitcher.condition.replay="Tampon de répétition" AdvSceneSwitcher.condition.replay.state.stopped="Tampon de répétition arrêté" AdvSceneSwitcher.condition.replay.state.started="Tampon de répétition démarré" @@ -426,7 +426,7 @@ AdvSceneSwitcher.condition.stats.condition.above="au-dessus de" AdvSceneSwitcher.condition.stats.condition.equals="égal à" AdvSceneSwitcher.condition.stats.condition.below="en dessous de" AdvSceneSwitcher.condition.stats.dockHint="Vous pouvez ouvrir le dock \"Statistiques\" pour voir l'état actuel" -AdvSceneSwitcher.condition.stats.entry="{{stats}} est {{condition}} {{value}}" +AdvSceneSwitcher.condition.stats.entry="{{stats}}est{{condition}}{{value}}" AdvSceneSwitcher.condition.profile="Profil" AdvSceneSwitcher.condition.profile.entry="Le profil actif actuel est{{profiles}}" AdvSceneSwitcher.condition.websocket="Websocket" @@ -434,7 +434,7 @@ AdvSceneSwitcher.condition.websocket.type.request="Demande de commutation de sc AdvSceneSwitcher.condition.websocket.type.event="Événement de commutation de scène" AdvSceneSwitcher.condition.websocket.useRegex="Utiliser des expressions régulières" AdvSceneSwitcher.condition.websocket.entry.request="{{type}}a été reçu :" -AdvSceneSwitcher.condition.websocket.entry.event="{{type}}a été reçu de{{connection}} :" +AdvSceneSwitcher.condition.websocket.entry.event="{{type}}a été reçu de{{connection}}:" AdvSceneSwitcher.condition.variable="Variable" AdvSceneSwitcher.condition.variable.type.compare="est égal à" AdvSceneSwitcher.condition.variable.type.empty="est vide" @@ -594,15 +594,15 @@ AdvSceneSwitcher.action.hotkey.leftMeta="Méta gauche" AdvSceneSwitcher.action.hotkey.rightMeta="Touche Droite Meta" AdvSceneSwitcher.action.hotkey.onlyOBS="Envoyer la pression de touche uniquement à OBS" AdvSceneSwitcher.action.hotkey.disabled="Impossible de simuler des pressions de touche globales - la fonctionnalité est limitée à l'envoi de la pression de touche à OBS uniquement !" -AdvSceneSwitcher.action.hotkey.entry.custom="Appuyer sur {{actionType}} {{keys}} pendant {{duration}}" -AdvSceneSwitcher.action.hotkey.entry.obs="Appuyer sur {{actionType}} {{hotkeyType}} {{obsHotkeys}}" +AdvSceneSwitcher.action.hotkey.entry.custom="Appuyer sur{{actionType}}{{keys}}pendant{{duration}}" +AdvSceneSwitcher.action.hotkey.entry.obs="Appuyer sur{{actionType}}{{hotkeyType}}{{obsHotkeys}}" AdvSceneSwitcher.action.sceneOrder="Ordre des éléments de la scène" AdvSceneSwitcher.action.sceneOrder.type.moveUp="Déplacer vers le haut" AdvSceneSwitcher.action.sceneOrder.type.moveDown="Déplacer vers le bas" AdvSceneSwitcher.action.sceneOrder.type.moveTop="Déplacer en haut" AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Déplacer en bas" AdvSceneSwitcher.action.sceneOrder.type.movePosition="Déplacer à la position" -AdvSceneSwitcher.action.sceneOrder.entry="Sur {{scenes}} {{actions}} {{sources}} {{position}}" +AdvSceneSwitcher.action.sceneOrder.entry="Sur{{scenes}}{{actions}}{{sources}}{{position}}" AdvSceneSwitcher.action.sceneTransform="Transformation de l'élément de la scène" AdvSceneSwitcher.action.sceneTransform.type.manual="Transform" AdvSceneSwitcher.action.sceneTransform.type.reset="Réinitialiser la transformation" @@ -615,11 +615,11 @@ AdvSceneSwitcher.action.sceneTransform.type.centerToScreen="Centrer à l'écran" AdvSceneSwitcher.action.sceneTransform.type.centerVertically="Centrer verticalement" AdvSceneSwitcher.action.sceneTransform.type.centerHorizontally="Centrer horizontalement" AdvSceneSwitcher.action.sceneTransform.getTransform="Obtenir la transformation" -AdvSceneSwitcher.action.sceneTransform.entry="Sur {{scenes}} {{action}} {{rotation}} {{sources}}" +AdvSceneSwitcher.action.sceneTransform.entry="Sur{{scenes}}{{action}}{{rotation}}{{sources}}" AdvSceneSwitcher.action.file="Fichier" AdvSceneSwitcher.action.file.type.write="Écrire" AdvSceneSwitcher.action.file.type.append="Ajouter" -AdvSceneSwitcher.action.file.entry="{{actions}} vers {{filePath}} :" +AdvSceneSwitcher.action.file.entry="{{actions}}vers{{filePath}}:" AdvSceneSwitcher.action.studioMode="Mode studio" AdvSceneSwitcher.action.studioMode.type.swap="Permuter la scène de prévisualisation et la scène du programme" AdvSceneSwitcher.action.studioMode.type.setScene="Définir la scène de prévisualisation sur" @@ -630,15 +630,15 @@ AdvSceneSwitcher.action.transition.type.scene="Transition de scène" AdvSceneSwitcher.action.transition.type.sceneOverride="Remplacement de la transition de scène" AdvSceneSwitcher.action.transition.type.sourceShow="Transition d'affichage de la source" AdvSceneSwitcher.action.transition.type.sourceHide="Transition de masquage de la source" -AdvSceneSwitcher.action.transition.entry.line1="Modifier {{type}} {{scenes}} {{sources}}" -AdvSceneSwitcher.action.transition.entry.line2="{{setTransition}} Définir le type de transition sur {{transitions}}" -AdvSceneSwitcher.action.transition.entry.line3="{{setDuration}} Définir la durée de la transition à {{duration}} secondes" +AdvSceneSwitcher.action.transition.entry.line1="Modifier{{type}}{{scenes}}{{sources}}" +AdvSceneSwitcher.action.transition.entry.line2="{{setTransition}}Définir le type de transition sur{{transitions}}" +AdvSceneSwitcher.action.transition.entry.line3="{{setDuration}}Définir la durée de la transition à{{duration}}secondes" AdvSceneSwitcher.action.timer="Minuterie" AdvSceneSwitcher.action.timer.type.pause="Mettre en pause" AdvSceneSwitcher.action.timer.type.continue="Continuer" AdvSceneSwitcher.action.timer.type.reset="Réinitialiser" AdvSceneSwitcher.action.timer.type.setTimeRemaining="Définir le temps restant de" -AdvSceneSwitcher.action.timer.entry="{{timerAction}} minuteries sur {{macros}} {{duration}}" +AdvSceneSwitcher.action.timer.entry="{{timerAction}}minuteries sur{{macros}}{{duration}}" AdvSceneSwitcher.action.random="Aléatoire" AdvSceneSwitcher.action.random.allowRepeat="Autoriser l'exécution consécutive du même macro" AdvSceneSwitcher.action.random.entry="Exécuter au hasard l'un des macros suivants (les macros en pause sont ignorées)" @@ -654,11 +654,11 @@ AdvSceneSwitcher.action.screenshot.type.source="Source" AdvSceneSwitcher.action.screenshot.type.scene="Scène" AdvSceneSwitcher.action.screenshot.mainOutput="Sortie principale d'OBS" AdvSceneSwitcher.action.screenshot.blackscreenNote="Les sources ou les scènes qui ne sont pas toujours rendues peuvent entraîner des parties de captures d'écran vides." -AdvSceneSwitcher.action.screenshot.entry="Capturer {{targetType}} {{sources}} {{scenes}} et enregistrer à l'emplacement {{saveType}}" +AdvSceneSwitcher.action.screenshot.entry="Capturer{{targetType}}{{sources}}{{scenes}}et enregistrer à l'emplacement{{saveType}}" AdvSceneSwitcher.action.profile="Profil" -AdvSceneSwitcher.action.profile.entry="Changer le profil actif vers {{profiles}}" +AdvSceneSwitcher.action.profile.entry="Changer le profil actif vers{{profiles}}" AdvSceneSwitcher.action.sceneCollection="Collection de scènes" -AdvSceneSwitcher.action.sceneCollection.entry="Changer la collection de scènes active vers {{sceneCollections}}" +AdvSceneSwitcher.action.sceneCollection.entry="Changer la collection de scènes active vers{{sceneCollections}}" AdvSceneSwitcher.action.sceneCollection.warning="Note : Toutes les actions suivantes ne seront pas exécutées car le changement de collection de scènes rechargera également les paramètres du commutateur de scènes. L'action de collection de scènes sera ignorée lorsque la fenêtre des paramètres est ouverte." AdvSceneSwitcher.action.sequence="Séquence" AdvSceneSwitcher.action.sequence.entry="Chaque fois que cette action est effectuée, exécutez le macro suivant dans la liste (les macros en pause sont ignorés)" @@ -674,17 +674,17 @@ AdvSceneSwitcher.action.websocket.type.request="Requête" AdvSceneSwitcher.action.websocket.type.event="Événement" AdvSceneSwitcher.action.websocket.settingsConflictGeneric="Possible conflit de paramètres : Sélection de message websocket générique avec une connexion qui suit le protocole OBS !" AdvSceneSwitcher.action.websocket.settingsConflictOBS="Possible conflit de paramètres : Connexion sélectionnée qui ne prend en charge que des messages websocket génériques, alors que le type de message nécessite le protocole OBS !" -AdvSceneSwitcher.action.websocket.entry.sceneSwitcher.request="Envoyer {{api}} de type {{type}} via {{connection}}" -AdvSceneSwitcher.action.websocket.entry.sceneSwitcher.event="Envoyer {{api}} de type {{type}} aux clients connectés" -AdvSceneSwitcher.action.websocket.entry.generic="Envoyer {{api}} via {{connection}}" +AdvSceneSwitcher.action.websocket.entry.sceneSwitcher.request="Envoyer{{api}}de type{{type}}via{{connection}}" +AdvSceneSwitcher.action.websocket.entry.sceneSwitcher.event="Envoyer{{api}}de type{{type}}aux clients connectés" +AdvSceneSwitcher.action.websocket.entry.generic="Envoyer{{api}}via{{connection}}" AdvSceneSwitcher.action.http="HTTP" AdvSceneSwitcher.action.http.setHeaders="Définir les en-têtes" AdvSceneSwitcher.action.http.headers="En-têtes :" AdvSceneSwitcher.action.http.addHeader="Ajouter un en-tête" AdvSceneSwitcher.action.http.type.get="GET" AdvSceneSwitcher.action.http.type.post="POST" -AdvSceneSwitcher.action.http.entry.line1="Envoyer {{method}} vers {{url}}" -AdvSceneSwitcher.action.http.entry.line2="Délai d'attente : {{timeout}} secondes" +AdvSceneSwitcher.action.http.entry.line1="Envoyer{{method}}vers{{url}}" +AdvSceneSwitcher.action.http.entry.line2="Délai d'attente :{{timeout}}secondes" AdvSceneSwitcher.action.variable="Variable" AdvSceneSwitcher.action.variable.type.set="Définir sur une valeur fixe" AdvSceneSwitcher.action.variable.type.append="Ajouter" @@ -710,8 +710,8 @@ AdvSceneSwitcher.action.variable.invalidSelection="Sélection invalide !" AdvSceneSwitcher.action.variable.actionNoVariableSupport="La récupération de valeurs de variables à partir d'actions %1 n'est pas prise en charge !" AdvSceneSwitcher.action.variable.conditionNoVariableSupport="La récupération de valeurs de variables à partir de conditions %1 n'est pas prise en charge !" AdvSceneSwitcher.action.variable.currentSegmentValue="Valeur actuelle :" -AdvSceneSwitcher.action.variable.entry.substringIndex="Début de la sous-chaîne : {{subStringStart}} Taille de la sous-chaîne : {{subStringSize}}" -AdvSceneSwitcher.action.variable.entry.substringRegex="Attribuer la valeur du match {{regexMatchIdx}} en utilisant une expression régulière :" +AdvSceneSwitcher.action.variable.entry.substringIndex="Début de la sous-chaîne :{{subStringStart}}Taille de la sous-chaîne :{{subStringSize}}" +AdvSceneSwitcher.action.variable.entry.substringRegex="Attribuer la valeur du match{{regexMatchIdx}}en utilisant une expression régulière :" AdvSceneSwitcher.action.variable.entry.userInput.customPrompt="{{useCustomPrompt}}Utiliser un message personnalisé{{inputPrompt}}" AdvSceneSwitcher.action.variable.entry.userInput.placeholder="{{useInputPlaceholder}}Remplir avec un indicateur de position{{inputPlaceholder}}" AdvSceneSwitcher.action.projector="Projecteur" @@ -723,17 +723,17 @@ AdvSceneSwitcher.action.projector.type.multiview="Multivue" AdvSceneSwitcher.action.projector.display="Affichage" AdvSceneSwitcher.action.projector.windowed="Fenêtré" AdvSceneSwitcher.action.projector.fullscreen="Plein écran" -AdvSceneSwitcher.action.projector.entry="Ouvrir le projecteur {{windowTypes}} de {{types}} {{scenes}} {{sources}}" -AdvSceneSwitcher.action.projector.entry.monitor="sur {{monitors}}" +AdvSceneSwitcher.action.projector.entry="Ouvrir le projecteur{{windowTypes}}de{{types}}{{scenes}}{{sources}}" +AdvSceneSwitcher.action.projector.entry.monitor="sur{{monitors}}" AdvSceneSwitcher.action.midi="MIDI" -AdvSceneSwitcher.action.midi.entry="Envoyer un message à {{device}} :" -AdvSceneSwitcher.action.midi.entry.listen="Définir la sélection de messages MIDI sur les messages entrants de {{listenDevices}} : {{listenButton}}" +AdvSceneSwitcher.action.midi.entry="Envoyer un message à{{device}}:" +AdvSceneSwitcher.action.midi.entry.listen="Définir la sélection de messages MIDI sur les messages entrants de{{listenDevices}}:{{listenButton}}" AdvSceneSwitcher.action.osc="Open Sound Control" AdvSceneSwitcher.action.sceneLock="Verrouillage de l'élément de scène" AdvSceneSwitcher.action.sceneLock.type.lock="verrouiller" AdvSceneSwitcher.action.sceneLock.type.unlock="déverrouiller" AdvSceneSwitcher.action.sceneLock.type.toggle="basculer le verrouillage de" -AdvSceneSwitcher.action.sceneLock.entry="Sur {{scenes}} {{actions}} {{sources}}" +AdvSceneSwitcher.action.sceneLock.entry="Sur{{scenes}}{{actions}}{{sources}}" AdvSceneSwitcher.action.twitch="Twitch" AdvSceneSwitcher.action.twitch.type.title="Définir le titre du flux" AdvSceneSwitcher.action.twitch.type.category="Définir la catégorie du flux" @@ -741,7 +741,7 @@ AdvSceneSwitcher.action.twitch.type.marker="Create stream marker" AdvSceneSwitcher.action.twitch.type.clip="Create stream clip" AdvSceneSwitcher.action.twitch.type.commercial="Démarrer une publicité d'une durée de" AdvSceneSwitcher.action.twitch.categorySelectionDisabled="Impossible de sélectionner une catégorie sans avoir d'abord sélectionné un compte Twitch !" -AdvSceneSwitcher.action.twitch.entry="Sur {{account}} {{actions}} {{streamTitle}} {{category}} {{manualCategorySearch}} {{markerDescription}} {{clipHasDelay}} {{duration}}" +AdvSceneSwitcher.action.twitch.entry.line1="Sur{{account}}{{actions}}{{streamTitle}}{{category}}{{manualCategorySearch}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementMessage}}{{announcementColor}}" AdvSceneSwitcher.action.twitch.tokenPermissionsInsufficient="Permissions of selected token are insufficient to perform selected action!" AdvSceneSwitcher.action.twitch.clip.hasDelay="Add a slight delay before capturing the clip" AdvSceneSwitcher.action.twitch.marker.description="Describe marker" @@ -752,10 +752,10 @@ AdvSceneSwitcher.transitionTab.title="Transition" AdvSceneSwitcher.transitionTab.transitionForAToB="Utiliser une transition pour le passage automatisé de la scène A à la scène B" AdvSceneSwitcher.transitionTab.transitionsHelp="
Ces paramètres n'affectent que les transitions provoquées par le commutateur de scènes - Consultez la Table de transitions si vous souhaitez les configurer pour des changements de scène manuels.
Les paramètres définis ici ont la priorité sur les paramètres de transition configurés ailleurs dans le commutateur de scènes.
Cliquez sur le symbole plus ci-dessous pour ajouter une nouvelle entrée.