Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
tutoriel:script_shell [Le 20/02/2022, 09:00]
88.170.129.244 [Les arguments en ligne de commande]
tutoriel:script_shell [Le 29/02/2024, 12:55] (Version actuelle)
Amiralgaby ancienne révision (Le 11/09/2022, 12:20) restaurée
Ligne 3: Ligne 3:
 ---- ----
  
-loadstring(game:HttpGet("​https://raw.githubusercontent.com/wally-rblx/​funky-friday-autoplay/​main/​main.lua",true))()+====== Introduction aux scripts shell ====== 
 + 
 +Un script shell permet d'​automatiser une série d'​opérations. Il se présente sous la forme d'un fichier contenant une ou plusieurs commandes qui  seront exécutées de manière séquentielle. 
 +<code bash> 
 +#​!/​bin/​bash 
 +# This script will take an animated GIF and delete every other frame 
 +# Accepts two parametersinput file and output file 
 +# Usage./<​scriptfilename>​ input.gif output.gif 
 + 
 +# Make a copy of the file 
 +cp "​$1"​ "​$2"​ 
 + 
 +# Get the number of frames 
 +numframes=$(gifsicle ​--info "$1" \ 
 +              | grep --perl-regexp --only-matching '\d+ images'​ \ 
 +              | grep --perl-regexp --only-matching '​\d+'​) 
 + 
 +# Deletion 
 +let i=0 
 +while test $i -lt $numframes 
 +do 
 +    rem=$(( $i % 2 )
 + 
 +    if test $rem -eq 0 
 +    then 
 +        gifsicle "​$2"​ --delete "#"​$(($i/2)) -o "​$2"​ 
 +    fi 
 + 
 +    let i=i+1  
 +done 
 +</​code>​
  
 =====Pour faire qu'un script soit exécutable ===== =====Pour faire qu'un script soit exécutable =====
Ligne 9: Ligne 39:
  
 Votre script est un simple fichier texte, par défaut il s'​ouvre donc avec l'​éditeur de texte défini par défaut (ex : [[:​gedit|Gedit]] dans une session Unity ou Gnome).\\ Votre script est un simple fichier texte, par défaut il s'​ouvre donc avec l'​éditeur de texte défini par défaut (ex : [[:​gedit|Gedit]] dans une session Unity ou Gnome).\\
-Pour qu'il soit autorisé à se lancer en tant que programme, il faut modifier ses propriétés.\\ +Pour qu'il soit autorisé à se lancer en tant que programme, il faut modifier ses propriétés.
 Pour cela faites un clic droit sur son icône, et dans l'​onglet "​Permissions"​ des "​Propriétés",​ cocher la case //"​autoriser l'​exécution du fichier comme un programme"//​. Pour cela faites un clic droit sur son icône, et dans l'​onglet "​Permissions"​ des "​Propriétés",​ cocher la case //"​autoriser l'​exécution du fichier comme un programme"//​.
  
Ligne 48: Ligne 78:
  
 Ajouter un répertoire au PATH peut donc être très pratique. Par convention, ce répertoire s'​appelle **bin** et se place dans votre répertoire personnel. Si votre répertoire personnel est /home/toto, ce répertoire sera donc **/​home/​toto/​bin**. Ajouter un répertoire au PATH peut donc être très pratique. Par convention, ce répertoire s'​appelle **bin** et se place dans votre répertoire personnel. Si votre répertoire personnel est /home/toto, ce répertoire sera donc **/​home/​toto/​bin**.
-Pour pouvoir utiliser ​mes scripts en tapant directement leur nom (sans le "​./"​) depuis n'​importe quel répertoire de mon ordinateur, il me suffit d'​indiquer au shell de chercher aussi dans ce nouveau dossier en l'​ajoutant au PATH.+Pour pouvoir utiliser ​vos scripts en tapant directement leur nom (sans le "​./"​) depuis n'​importe quel répertoire de votre ordinateur, il vous suffit d'​indiquer au shell de chercher aussi dans ce nouveau dossier en l'​ajoutant au PATH.
 Pour ceci, il suffit de faire : Pour ceci, il suffit de faire :
   export PATH=$PATH:​$HOME/​bin   export PATH=$PATH:​$HOME/​bin
Ligne 74: Ligne 104:
   * ksh (<=> ksh88 sur Solaris et équivaut à ksh93 sur les autres UNIX/Linux cf.[[http://​en.wikipedia.org/​wiki/​Korn_shell#​History|Korn shell History]]): shells korn écrits par David Korn, pdksh (Public Domain Korn Shell <=> ksh88) ;   * ksh (<=> ksh88 sur Solaris et équivaut à ksh93 sur les autres UNIX/Linux cf.[[http://​en.wikipedia.org/​wiki/​Korn_shell#​History|Korn shell History]]): shells korn écrits par David Korn, pdksh (Public Domain Korn Shell <=> ksh88) ;
   * rc : shell C, lui aussi conçu par le projet GNU ;   * rc : shell C, lui aussi conçu par le projet GNU ;
-  * tclsh : shell utilisant Tcl ;                         +  * tclsh : shell utilisant Tcl ; 
-  * wish : shell utilisant Tk .      +  * wish : shell utilisant Tk .
  
 Il existe bien entendu beaucoup d'​autres types de shells.\\ Pour savoir quel type de shell est présent sur une machine, aller dans un terminal et taper la commande **ps**. Il existe bien entendu beaucoup d'​autres types de shells.\\ Pour savoir quel type de shell est présent sur une machine, aller dans un terminal et taper la commande **ps**.
Ligne 83: Ligne 113:
 ===== Les variables ===== ===== Les variables =====
 Il faut savoir que en bash les variables sont toutes des chaînes de caractères.\\ Il faut savoir que en bash les variables sont toutes des chaînes de caractères.\\
-Cela dépendra de son USAGE, pour une opération arithmétique prochaine voir : let ma_variable sinon pour conserver une valeur : +Cela dépendra de son USAGE, pour une opération arithmétique prochaine voir : let ma_variable sinon pour conserver une valeur :
 il suffit de lui donner un nom et une valeur avec l'​affectation égale : il suffit de lui donner un nom et une valeur avec l'​affectation égale :
 <code bash> <code bash>
Ligne 151: Ligne 181:
  
 Exemple: un sleep interactif pour illustrer $! (Cf. [[:​tutoriel:​script_shell#​les_fonctions|les fonctions]]).\\ ​ Exemple: un sleep interactif pour illustrer $! (Cf. [[:​tutoriel:​script_shell#​les_fonctions|les fonctions]]).\\ ​
-Pour déclarer un tableau, plusieurs méthodes :\\ +Pour déclarer un tableau, plusieurs méthodes :
 première méthode (compatible bash, zsh, et ksh93 mais pas ksh88, ni avec dash, qui est lancé par "​sh"​) : première méthode (compatible bash, zsh, et ksh93 mais pas ksh88, ni avec dash, qui est lancé par "​sh"​) :
 <code bash>​tab=("​John Smith" "Jane Doe"​)</​code>​ <code bash>​tab=("​John Smith" "Jane Doe"​)</​code>​
Ligne 185: Ligne 215:
 renverront la même réponse. renverront la même réponse.
  
-NB2 : les tableaux sont séparés par un séparateur défini : l'IFS.  +NB2 : les tableaux sont séparés par un séparateur défini : l'​IFS. 
-Par défaut l'IFS est composé des trois caractères : $' \t\n' soit espace, tabulation, saut de ligne. ​+Par défaut l'IFS est composé des trois caractères : $' \t\n' soit espace, tabulation, saut de ligne.
 Il peut être forcé sur un autre caractère. Il peut être forcé sur un autre caractère.
 <code bash>​IFS=$SEPARATEUR</​code>​ <code bash>​IFS=$SEPARATEUR</​code>​
Ligne 194: Ligne 224:
   * un caractère spécial : ($'​\t'​ : tabulation, $'​\n'​ : saut de ligne,...)   * un caractère spécial : ($'​\t'​ : tabulation, $'​\n'​ : saut de ligne,...)
  
---[[ +==== Les arguments en ligne de commande ====
-Change logs:+
  
-1/14/22 +Pour passer des arguments en ligne de commande c'est encore une fois très simpleChaque argument est numéroté et ensuite on l'​appelle par son numéro :
-    * first update of the new year! +
-    * added a settings saving / loading system. +
-    * added some save manager code for this ui library, not all option types are supported or tested.+
  
-12/5/21 +   ./test.sh powa noplay
-    * Fixed issues with noteTime calculation,​ causing some songs like Triple Trouble to breakReport bugs as always+
  
-11/9/21 +Voici notre test.sh 
-    + Added support for new modes (9Key for example)+<code bash> 
 +#!/bin/sh 
 +echo $3 
 +echo $2 
 +</​code>​
  
-9/26/21  +Notez que $0 est le nom du fichier.
-    + Added '​Unload'​ +
-    * Fixed issues with accuracy.+
  
-9/​25/​21 ​(patch 1) +''​shift''​ est une commande très pratique lorsque vous traitez des arguments en ligne de commande. Elle permet de faire "​défiler"​ les arguments ​($0, $1, $2, …). C'est à dire que le contenu de $1 passe dans $0celui de $2 dans $1 et ainsi de suite. Il est tout à fait possible de traiter les arguments avec ''​for ​in $*; do''​ mais lorsque vous aurez des options du style ''​–title "​mon_titre"''​ il sera très laborieux de récupérer la valeur ''"​mon_titre"''​.
-    * Added a few sanity checks +
-    * Fixed some errors +
-    * Should finally fix invisible notes (if it doesnt, i hate this game)+
  
-9/25/21 +Voici un exemple de script où vous devez vous souvenir de ce que vous avez écrit ​(un petit jeu de mémoirequoi: 
-    * Code refactoring. + <code bash> 
-    * Fixed unsupported exploit check +#!/bin/sh 
-    * Implemented safer URL loading routine. +clear # Un peu facile si la commande reste au dessus ​:-) 
-    * Tweaked autoplayer ​(implemented hitbox offsetuses game code to calculate score and hit type now+until $# 
- +do 
-9/19/21 +  ​echo ​-"Taper l'option suivante : 
-   * Miss actually ignores the note. +  read Reslt 
- +  if "$Reslt" = "$1" ]; then 
-8/20/21 +    ​echo "Bien joué !
-   This update was provided by Sezei (https://github.com/​greasemonkey123/​ff-bot-new) +  else 
-       * I renamed some stuff and changed their default '​Autoplayer bind'​ +    ​echo "Non mais quand même !!! C'ÉTAIT $ET NON PAS $Reslt PETIT FRIPON !!!" 
- +    ​sleep 3 Juste pour le fun du script qui rage ;-p 
-   + Added 'Miss chance'​ +    ​echo ​"Donc je te bannis de ubuntu-fr.org ! Et toc !! Tu ne peux rien contre moi !!!" 
-   + Added '​Release delay' (note: higher values means a higher chance to miss) +    ​exit 1 
-   + Added '​Autoplayer bind'​ +  fi 
-   * Added new credits +  ​shift On défile 
-   * Made folder names more clear +done 
- +echo "Vous avez réussi ​!" 
-8/2/21 +</code>
-    ! KRNL has since been fixed, enjoy! +
- +
-    + Added '​Manual'​ mode which allows you to force the notes to hit a specific type by holding down a keybind. +
-    * Switched fastWait and fastSpawn to Roblox'​s task libraries +
-    * Attempted to fix '​invalid key to next' errors +
- +
-5/12/21 +
-    * Attempted to fix the autoplayer missing as much. +
- +
-5/16/21 +
-    * Attempt to fix invisible notes. +
-    * Added hit chances & an autoplayer toggle +
-    ! Hit chances are a bit rough but should work. +
- +
-Information: +
-    Officially supported: Synapse X, Script-Ware, KRNL, Fluxus +
-    Needed functions: setthreadcontext,​ getconnections,​ getgc, getloaodedmodules  +
- +
-    You can find contact information on the GitHub repository (https://​github.com/​wally-rblx/​funky-friday-autoplay+
---]] +
- +
-local start = tick() +
-local client = game:​GetService('​Players'​).LocalPlayer;​ +
-local set_identity = (type(syn) == '​table'​ and syn.set_thread_identity) or setidentity or setthreadcontext +
- +
-local function fail(r) return client:​Kick(r) end +
- +
--- gracefully handle errors when loading external scripts +
--- added a cache to make hot reloading a bit faster +
- +
-local usedCache = shared.__urlcache and next(shared.__urlcache) ~= nil +
- +
-shared.__urlcache = shared.__urlcache or {} +
-local function urlLoad(url) +
-    local success, result +
- +
-    if shared.__urlcache[url] then +
-        success, result ​true, shared.__urlcache[url+
-    ​else +
-        success, result = pcall(game.HttpGet,​ game, url) +
-    end +
- +
-    if (not success) then +
-        return fail(string.format('​Failed to GET url %q for reason: %q', url, tostring(result))) +
-    end +
- +
-    local fn, err = loadstring(result) +
-    if (type(fn) ~= '​function'​) then +
-        return fail(string.format('​Failed to loadstring url %q for reason: %q', url, tostring(err))) +
-    end +
- +
-    local results = { pcall(fn) } +
-    if (not results[1]) then +
-        return fail(string.format('​Failed to initialize url %q for reason: %q', url, tostring(results[2]))) +
-    end +
- +
-    shared.__urlcache[url] = result +
-    return unpack(results,​ 2) +
-end +
- +
--- attempt to block imcompatible exploits +
--- rewrote because old checks literally did not work +
-if type(set_identity) ~= '​function'​ then return fail('​Unsupported exploit (missing ​"set_thread_identity"​)') end +
-if type(getconnections) ~= '​function'​ then return fail('​Unsupported exploit (missing ​"getconnections"​)'​) end +
-if type(getloadedmodules) ~= '​function'​ then return fail('​Unsupported exploit (misssing "​getloadedmodules"​)'​) end +
-if type(getgc) ~= '​function'​ then return fail('​Unsupported exploit (misssing ​"getgc")') end +
- +
-local library ​urlLoad("https://​raw.githubusercontent.com/​wally-rblx/​uwuware-ui/​main/​main.lua"​) +
-local akali = urlLoad("​https://​gist.githubusercontent.com/​wally-rblx/​e010db020afe8259048a0c3c7262cdf8/​raw/​76ae0921ac9bd3215017e635d2c1037a37262240/​notif.lua"​) +
- +
-local httpService = game:​GetService('​HttpService'​) +
- +
-local framework, scrollHandler +
-local counter = 0 +
- +
-while true do +
-    for _, obj in next, getgc(true) do +
-        if type(obj) == '​table'​ and rawget(obj, '​GameUI'​) then +
-            framework = obj; +
-            break +
-        end  +
-    end +
- +
-    for _, module in next, getloadedmodules() do +
-        if module.Name == '​ScrollHandler'​ then +
-            scrollHandler = module; +
-            break; +
-        end +
-    end +
- +
-    if (type(framework) == '​table'​) and (typeof(scrollHandler) == '​Instance'​) then +
-        break +
-    end +
- +
-    counter = counter + 1 +
-    if counter > 6 then +
-        fail(string.format('​Failed to load game dependencies. Details: %s, %s', type(framework),​ typeof(scrollHandler))) +
-    end +
-    wait(1) +
-end +
- +
-local runService = game:​GetService('​RunService'​) +
-local userInputService = game:​GetService('​UserInputService'​) +
-local virtualInputManager = game:​GetService('​VirtualInputManager'​) +
- +
-local random = Random.new() +
- +
-local task = task or getrenv().task;​ +
-local fastWait, fastSpawn = task.wait, task.spawn;​ +
- +
--- firesignal implementation +
--- hitchance rolling +
-local fireSignal, rollChance do +
-    -- updated for script-ware or whatever +
-    -- attempted to update for krnl +
- +
-    function fireSignal(target,​ signal, ...) +
-        -- getconnections with InputBegan / InputEnded does not work without setting Synapse to the game's context level +
-        set_identity(2) +
-        local didFire = false +
-        for _, signal in next, getconnections(signal) do +
-            if type(signal.Function) == '​function'​ and islclosure(signal.Function) then +
-                local scr = rawget(getfenv(signal.Function),​ '​script'​) +
-                if scr == target then +
-                    didFire = true +
-                    pcall(signal.Function,​ ...) +
-                end +
-            end +
-        end +
-        -- if not didFire then fail"couldnt fire input signal"​ end +
-        set_identity(7) +
-    end +
- +
-    -- uses a weighted random system +
-    -- its a bit scuffed rn but it works good enough +
- +
-    function rollChance() +
-        if (library.flags.autoPlayerMode == '​Manual'​) then +
-            if (library.flags.sickHeld) then return '​Sick'​ end +
-            if (library.flags.goodHeld) then return '​Good'​ end +
-            if (library.flags.okayHeld) then return '​Ok'​ end +
-            if (library.flags.missHeld) then return '​Bad'​ end +
- +
-            return '​Bad'​ -- incase if it cant find one +
-        end +
- +
-        local chances = { +
-            { type = '​Sick',​ value = library.flags.sickChance }, +
-            { type = '​Good',​ value = library.flags.goodChance }, +
-            { type = '​Ok',​ value = library.flags.okChance }, +
-            { type = '​Bad',​ value = library.flags.badChance }, +
-            { type = '​Miss'​ , value = library.flags.missChance }, +
-        } +
- +
-        table.sort(chances,​ function(a, b) +
-            return a.value > b.value +
-        end) +
- +
-        local sum = 0; +
-        for i = 1, #chances do +
-            sum += chances[i].value +
-        end +
- +
-        if sum == 0 then +
-            -- forgot to change this before? +
-            -- fixed 6/5/21 +
- +
-            return chances[random:​NextInteger(1,​ #​chances)].type +
-        end +
- +
-        local initialWeight = random:​NextInteger(0,​ sum) +
-        local weight = 0; +
- +
-        for i = 1, #chances do +
-            weight = weight + chances[i].value +
- +
-            if weight > initialWeight ​then +
-                return chances[i].type +
-            end +
-        end +
- +
-        return '​Sick'​ -- just incase it fails? +
-    ​end +
-end +
- +
- +
-local function notify(text,​ duration) +
-    return akali.Notify({ +
-        Title = 'Funky friday autoplayer',​  +
-        Description = text, +
-        Duration = duration or 1, +
-    }) +
-end +
- +
-library.notify = notify +
- +
--- save manager +
-local saveManager = {} do +
-    local defaultSettings = [[{"Funky Friday":​{"​goodChance":​{"​value":​0,"​type":"​slider"​},"​badChance":​{"​value":​0,"​type":"​slider"​},"​okChance":​{"​value":​0,"​type":"​slider"​},"​autoPlayer":​{"​state":​false,"​type":"​toggle"​},"​goodBind":​{"​key":"​Two","​type":"​bind"​},"​sickChance":​{"​value":​100,"​type":"​slider"​},"​okBind":​{"​key":"​Three","​type":"​bind"​},"​sickBind":​{"​key":"​One","​type":"​bind"​},"​Menu toggle":​{"​key":"​Delete","​type":"​bind"​},"​secondaryPressMode":​{"​state":​false,"​type":"​toggle"​},"​autoDelay":​{"​value":​50,"​type":"​slider"​},"​autoPlayerToggle":​{"​key":"​End","​type":"​bind"​},"​badBind":​{"​key":"​Four","​type":"​bind"​},"​autoPlayerMode":​{"​value":"​Chances","​type":"​list"​},"​missChance":​{"​value":​0,"​type":"​slider"​}}}]] +
-    local optionTypes = { +
-        toggle = { +
-            Save = function(option) +
-                return { type = '​toggle',​ state = option.state } +
-            end, +
-            Load = function(option,​ data) +
-                option:​SetState(data.state) +
-            end +
-        }, +
-        bind = { +
-            Save = function(option) +
-                return { type = '​bind',​ key = option.key } +
-            end, +
-            Load = function(option,​ data) +
-                option:​SetKey(data.key) +
-            end +
-        }, +
-        slider = { +
-            Save = function(option) +
-                return { type = '​slider',​ value = option.value } +
-            end, +
-            Load = function(option,​ data) +
-                option:​SetValue(data.value) +
-            end, +
-        }, +
-        color = { +
-            Save = function(option) +
-                return { type = '​color',​ color = option.color:​ToHex() } +
-            end, +
-            Load = function(option,​ data) +
-                option:​SetValue(Color3.fromHex(data.color)) +
-            end +
-        }, +
-        list = { +
-            Save = function(option) +
-                return { type = '​list',​ value = option.value } +
-            end, +
-            Load = function(option,​ data) +
-                option:​SetValue(data.value) +
-            end +
-        }, +
-    } +
- +
-    local function recurseLibraryOptions(root,​ callback) +
-        for _, option in next, root do +
-            if option.type == '​folder'​ then +
-                recurseLibraryOptions(option.options,​ callback) +
-            ​else +
-                callback(option) +
-            end +
-        end +
-    ​end +
- +
-    function saveManager:​SaveConfig(name) +
-        local data = {} +
- +
-        for _, window in next, library.windows do +
-            if window.title == '​Configs'​ then continue end +
- +
-            local storage = {} +
-            data[window.title] = storage +
- +
-            recurseLibraryOptions(window.options,​ function(option) +
-                local parser = optionTypes[option.type] +
-                if parser then +
-                    storage[option.flag] = parser.Save(option) +
-                end +
-            end) +
-        end +
- +
-        local s, err = pcall(writefile,​ '​funky_friday_autoplayer\\configs\\'​ .. name, httpService:​JSONEncode(data)) +
-        if not s then +
-            library.notify(string.format('​Failed to save config %q because %q', name, err), 2) +
-            if err == '​invalid extension'​ then +
-                library.notify('​Try adding a file extension after your config name. ex: "​.json",​ "​.txt",​ ".dat"'​, 2) +
-            end +
-            return +
-        end +
- +
-        library.refreshConfigs() +
-    end +
- +
-    function saveManager:​LoadConfig(name) +
-        local data +
-        if name == '​default'​ then +
-            data = defaultSettings +
-        else +
-            data = readfile('​funky_friday_autoplayer\\configs\\'​ .. name) +
-        end +
- +
-        local success, data = pcall(function() return httpService:​JSONDecode(data) end) +
-        if not success then  +
-            return library.notify(string.format('​Failed to load config %q because %q', name, data)) +
-        end +
- +
-        for _, window in next, library.windows do +
-            if window.title == '​Configs'​ then continue end +
- +
-            local storage = data[window.title] +
-            if not storage then continue end +
- +
-            recurseLibraryOptions(window.options,​ function(option) +
-                local parser = optionTypes[option.type] +
-                if parser then +
-                    parser.Load(option,​ storage[option.flag]) +
-                end +
-            end) +
-        end +
-    end +
- +
-end +
- +
--- autoplayer +
-local chanceValues do +
-    chanceValues = {  +
-        Sick = 96, +
-        Good = 92, +
-        Ok = 87, +
-        Bad = 75, +
-    } +
- +
-    local keyCodeMap = {} +
-    for _, enum in next, Enum.KeyCode:​GetEnumItems() do +
-        keyCodeMap[enum.Value] = enum +
-    end +
- +
-    if shared._unload then +
-        pcall(shared._unload) +
-    end +
- +
-    library.threads = {} +
-    function shared._unload() +
-        if shared._id then +
-            pcall(runService.UnbindFromRenderStep,​ runService, shared._id) +
-        end +
- +
-        if library.open then +
-            library:​Close() +
-        end +
- +
-        library.base:​ClearAllChildren() +
-        library.base:​Destroy() +
- +
-        for i = 1, #​library.threads do +
-            coroutine.close(library.threads[i]) +
-        end +
-    ​end +
- +
-    shared._id = httpService:​GenerateGUID(false) +
-    runService:​BindToRenderStep(shared._id,​ 1, function() +
-        if (not library.flags.autoPlayer) then return end +
-        if typeof(framework.SongPlayer.CurrentlyPlaying) ~= '​Instance'​ then return end +
-        if framework.SongPlayer.CurrentlyPlaying.ClassName ~= '​Sound'​ then return end +
- +
-        local arrows = {} +
-        for _, obj in next, framework.UI.ActiveSections do +
-            arrows[#arrows + 1] = obj; +
-        end +
- +
-        local count = framework.SongPlayer:​GetKeyCount() +
-        local mode = count .. '​Key'​ +
- +
-        local arrowData = framework.ArrowData[mode].Arrows +
- +
-        for idx = 1, #arrows do +
-            local arrow = arrows[idx] +
-            if type(arrow) ~= '​table'​ then +
-                continue +
-            end +
- +
-            local ignoredNoteTypes = { Death = true, ['Pea Note'] = true } +
- +
-            if type(arrow.NoteDataConfigs) == '​table'​ then  +
-                if ignoredNoteTypes[arrow.NoteDataConfigs.Type] then  +
-                    continue +
-                end +
-            end +
- +
-            if (arrow.Side == framework.UI.CurrentSide) and (not arrow.Marked) and framework.SongPlayer.CurrentlyPlaying.TimePosition > 0 then +
-                local indice = (arrow.Data.Position % count) +
-                local position = indice .. ''​ +
- +
-                if (position) then +
-                    local hitboxOffset = 0 do +
-                        local settings = framework.Settings;​ +
-                        local offset = type(settings) == '​table'​ and settings.HitboxOffset;​ +
-                        local value = type(offset) == '​table'​ and offset.Value;​ +
- +
-                        if type(value) == '​number'​ then +
-                            hitboxOffset = value; +
-                        end +
- +
-                        hitboxOffset = hitboxOffset / 1000 +
-                    end +
- +
-                    local songTime = framework.SongPlayer.CurrentTime do +
-                        local configs = framework.SongPlayer.CurrentSongConfigs +
-                        local playbackSpeed = type(configs) == '​table'​ and configs.PlaybackSpeed +
- +
-                        if type(playbackSpeed) ~= '​number'​ then +
-                            playbackSpeed = 1 +
-                        end +
- +
-                        songTime = songTime /  playbackSpeed +
-                    end +
- +
-                    local noteTime = math.clamp((1 ​math.abs(arrow.Data.Time - (songTime + hitboxOffset))) * 100, 0, 100) +
- +
-                    local result = rollChance() +
-                    arrow._hitChance = arrow._hitChance or result; +
- +
-                    local hitChance = (library.flags.autoPlayerMode == '​Manual'​ and result or arrow._hitChance) +
-                    if hitChance ~= "Miss" and noteTime >= chanceValues[arrow._hitChance] then +
-                        fastSpawn(function() +
-                            arrow.Marked = true; +
-                            local keyCode = keyCodeMap[arrowData[position].Keybinds.Keyboard[1]] +
- +
-                            if library.flags.secondaryPressMode then +
-                                virtualInputManager:​SendKeyEvent(true,​ keyCode, false, nil) +
-                            else +
-                                fireSignal(scrollHandler,​ userInputService.InputBegan,​ { KeyCode = keyCode, UserInputType = Enum.UserInputType.Keyboard }, false) +
-                            end +
- +
-                            if arrow.Data.Length > 0 then +
-                                fastWait(arrow.Data.Length + (library.flags.heldDelay / 1000)) +
-                            else +
-                                fastWait(library.flags.autoDelay / 1000) +
-                            end +
- +
-                            if library.flags.secondaryPressMode then +
-                                virtualInputManager:​SendKeyEvent(false,​ keyCode, false, nil) +
-                            else +
-                                fireSignal(scrollHandler,​ userInputService.InputEnded,​ { KeyCode = keyCode, UserInputType = Enum.UserInputType.Keyboard }, false) +
-                            end +
- +
-                            arrow.Marked = nil; +
-                        end) +
-                    end +
-                end +
-            end +
-        end +
-    end) +
-end +
- +
--- menu  +
- +
-local windows = { +
-    autoplayer = library:​CreateWindow('​Autoplayer'​),​ +
-    customization = library:​CreateWindow('​Customization'​),​ +
-    configs = library:​CreateWindow('​Configs'​),​ +
-    misc = library:​CreateWindow('​Miscellaneous'​) +
-+
- +
-local folder = windows.autoplayer:​AddFolder('​Main'​) do +
-    local toggle = folder:​AddToggle({ text = '​Autoplayer',​ flag = '​autoPlayer'​ }) +
- +
-    folder:​AddToggle({ text = '​Secondary press mode', flag = '​secondaryPressMode',​ callback = function() +
-        if library.flags.secondaryPressMode then  +
-            library.notify('​Only enable "​Secondary press mode" if the main autoplayer does not workIt may cause issues or not be as accurate!') +
-        end +
-    end }) -- alternate mode if something breaks on krml or whatever +
-    folder:​AddLabel({ text = "Enable if autoplayer breaks"​ }) +
- +
-    ​-- Fixed to use toggle:​SetState +
-    ​folder:​AddBind({ text = '​Autoplayer toggle',​ flag = '​autoPlayerToggle',​ key = Enum.KeyCode.End,​ callback = function() +
-        ​toggle:​SetState(not toggle.state) +
-    end }) +
- +
-    folder:​AddDivider() +
-    folder:​AddList({ text = '​Autoplayer mode', flag = '​autoPlayerMode',​ values = { '​Chances',​ '​Manual' ​ } }) +
-end +
- +
-local folder = windows.customization:​AddFolder('​Hit chances'​) do +
-    folder:​AddSlider({ text = 'Sick %', flag = '​sickChance',​ min = 0, max = 100, value = 100 }) +
-    folder:​AddSlider({ text = 'Good %', flag = '​goodChance',​ min = 0, max = 100, value = 0 }) +
-    folder:​AddSlider({ text = 'Ok %', flag = '​okChance',​ min = 0, max = 100, value = 0 }) +
-    folder:​AddSlider({ text = 'Bad %', flag = '​badChance',​ min = 0, max = 100, value = 0 }) +
-    folder:​AddSlider({ text = 'Miss %', flag = '​missChance',​ min = 0, max = 100, value = 0 }) +
-end +
- +
-local folder = windows.customization:​AddFolder('​Timing'​) do +
-    folder:​AddSlider({ text = '​Release delay (ms)', flag = '​autoDelay',​ min = 0, max = 500, value = 20 }) +
-    folder:​AddSlider({ text = 'Held delay (ms)', flag = '​heldDelay',​ min = -20, max = 100, value = -20 }) +
-end +
- +
-local folder = windows.customization:​AddFolder('​Keybinds'​) do +
-    folder:​AddBind({ text = '​Sick',​ flag = '​sickBind',​ key = Enum.KeyCode.One,​ hold = true, callback = function(val) library.flags.sickHeld = (not val) end, }) +
-    folder:​AddBind({ text = '​Good',​ flag = '​goodBind',​ key = Enum.KeyCode.Two,​ hold = true, callback = function(val) library.flags.goodHeld = (not val) end, }) +
-    folder:​AddBind({ text = '​Ok',​ flag = '​okBind',​ key = Enum.KeyCode.Three,​ hold = true, callback = function(val) library.flags.okayHeld = (not val) end, }) +
-    folder:​AddBind({ text = '​Bad',​ flag = '​badBind',​ key = Enum.KeyCode.Four,​ hold = true, callback = function(val) library.flags.missHeld = (not val) end, }) +
-end +
- +
-if type(readfile) == '​function'​ and type(writefile) == '​function'​ and type(makefolder) == '​function'​ and type(isfolder) == '​function'​ then +
-    if not isfolder('​funky_friday_autoplayer\\configs'​) then +
-        makefolder('​funky_friday_autoplayer'​) +
-        makefolder('​funky_friday_autoplayer\\configs'​) +
-    end +
- +
-    local window = windows.configs do +
-        window:​AddBox({ text = '​Config name', value = '',​ flag = '​configNameInput'​ }) +
-        library._configList = window:​AddList({ text = '​Config list', values = { '​default'​ }, flag = '​configList'​ }) +
-         +
-        window:​AddButton({ text = 'Save config',​ callback = function() +
-            local name = library.flags.configNameInput +
-            if name:​gsub('​ ', ''​) == ''​ then +
-                return notify('​Failed to save. [invalid config name]',​ 3) +
-            end +
- +
-            saveManager:​SaveConfig(name) +
-        end }) +
-         +
-        window:​AddButton({ text = 'Load config',​ callback = function() +
-            local name = library.flags.configList +
-             +
-            if name:​gsub('​ ', ''​) == ''​ then +
-                return notify('​Failed to load. [invalid config name]',​ 3) +
-            end +
- +
-            if not isfile('​funky_friday_autoplayer\\configs\\'​ .. name) then +
-                return notify('​Failed to load. [config does not exist]',​ 3) +
-            end +
- +
-            saveManager:​LoadConfig(name) +
-        end }) +
- +
-        window:​AddDivider() +
- +
-        function library.refreshConfigs() +
-            for _, value in next, library._configList.values do +
-                if value == '​default'​ then continue end +
-                library._configList:​RemoveValue(tostring(value)) +
-            end +
- +
-            local files = listfiles('​funky_friday_autoplayer\\configs'​) +
-            for i = 1, #files do +
-                ​files[i] = files[i]:​gsub('​funky_friday_autoplayer\\configs\\',​ ''​) +
-                ​library._configList:​AddValue(files[i]) +
-            end +
- +
-            if files[1] then +
-                library._configList:​SetValue(files[1]) +
-            else +
-                library._configList:​SetValue('​default'​) +
-            end +
-        end +
- +
-        window:​AddButton({ text = '​Refresh configs',​ callback = library.refreshConfigs }) +
-    end +
-    task.delay(1,​ library.refreshConfigs) +
-else +
-    notify('​Failed to create configs window due to your exploit missing certain file functions.',​ 2) +
-end +
- +
-local folder = windows.misc:​AddFolder('​Credits'​) do +
-    folder:​AddLabel({ text = 'Jan - UI library'​ }) +
-    folder:​AddLabel({ text = 'wally - Script'​ }) +
-    folder:​AddLabel({ text = 'Sezei - Contributor'​}) +
-    folder:​AddLabel({ text = '​aKinlei - Notifications'​}) +
-end +
- +
-windows.misc:​AddLabel({ text = '​Version 1.9a' }) +
-windows.misc:​AddLabel({ text = '​Updated 12/​11/​21'​ }) +
-windows.misc:​AddLabel({ text = 'i fixed stuff at 3 am' }) +
- +
-windows.misc:​AddDivider() +
-windows.misc:​AddButton({ text = '​Unload script',​ callback = function() +
-    shared._unload() +
-    library.notify('​Successfully unloaded script!', 2) +
-end }) +
- +
-windows.misc:​AddButton({ text = 'Copy discord',​ callback = function() +
-    if pcall(setclipboard,​ "​https:​//​wally.cool/​discord"​) then +
-        library.notify('​Successfully copied discord',​ 2) +
-    end +
-end }) +
- +
-windows.misc:​AddDivider() +
-windows.misc:​AddBind({ text = 'Menu toggle',​ key = Enum.KeyCode.Delete,​ callback = function() library:​Close() end })+
  
-library:​Init() 
-library.notify(string.format('​Loaded script in %.4f second(s)!\nUsed Http cache: %s', tick() - start, tostring(usedCache)),​ 3) 
 ==== L'​arithmétique ==== ==== L'​arithmétique ====
 <code bash>(( variable = 2 + $autre_var * 5 ))</​code>​ <code bash>(( variable = 2 + $autre_var * 5 ))</​code>​
Ligne 1249: Ligne 694:
 </​code>​ </​code>​
   ​   ​
-Comme vous l'avez sans doute remarqué, quand on appelle la fonction, on exécute simplement ce qu'on lui a défini au début, dans notre exemple, echo... et ls -l, on peut donc faire exécuter n'​importe quoi à une fonction. ​+Comme vous l'avez sans doute remarqué, quand on appelle la fonction, on exécute simplement ce qu'on lui a défini au début, dans notre exemple, echo... et ls -l, on peut donc faire exécuter n'​importe quoi à une fonction.
  
 Les fonctions peuvent être définies n'​importe où dans le code du moment qu'​elles sont définies avant d'​être utilisées. Même si en bash les variables sont globales, il est possible de les déclarer comme locales au sein d'une fonction en la précédant du mot clé local: local ma_fonction . Les fonctions peuvent être définies n'​importe où dans le code du moment qu'​elles sont définies avant d'​être utilisées. Même si en bash les variables sont globales, il est possible de les déclarer comme locales au sein d'une fonction en la précédant du mot clé local: local ma_fonction .
Ligne 1386: Ligne 831:
 ===== Exemples et exercices ===== ===== Exemples et exercices =====
  
-Comme indiqué dans la [[script_shell#​liens|section liens]] de cette page, de très bon exemples et exercices illustrent le cours disponible sur cette page :\\  +Comme indiqué dans la [[script_shell#​liens|section liens]] de cette page, de très bon exemples et exercices illustrent le cours disponible sur cette page : 
-[[http://​abs.traduc.org/​abs-5.3-fr/​apm.html|Guide avancé d'​écriture des scripts Bash - Une exploration en profondeur de l'art de la programmation shell]]+[[https://​abs.traduc.org/​abs-5.3-fr/​apm.html|Guide avancé d'​écriture des scripts Bash - Une exploration en profondeur de l'art de la programmation shell]]
  
 Aux structures décrites ci-dessus, il est nécessaire,​ pour réaliser des scripts poussés, de connaître les commandes shell les plus usitées.\\ Vous en trouverez une présentation sur cette autre page du wiki : [[projets:​ecole:​scripting:​initiation_au_shell]] . Aux structures décrites ci-dessus, il est nécessaire,​ pour réaliser des scripts poussés, de connaître les commandes shell les plus usitées.\\ Vous en trouverez une présentation sur cette autre page du wiki : [[projets:​ecole:​scripting:​initiation_au_shell]] .
  
-La programmation de script shell étant ouverte à tous, cela permet de bénéficier de nombreux scripts pour des applications très variées ; cependant, **la plupart sont proposés sans aucune garantie**.\\ +La programmation de script shell étant ouverte à tous, cela permet de bénéficier de nombreux scripts pour des applications très variées ; cependant, **la plupart sont proposés sans aucune garantie**.
 Vous pourrez trouver une liste de scripts pouvant servir d'​exemples sur la page [[:​scripts_utiles|scripts utiles]] du wiki. Vous pourrez trouver une liste de scripts pouvant servir d'​exemples sur la page [[:​scripts_utiles|scripts utiles]] du wiki.
  
-Une fois vos armes faites, proposez vos contributions sur le topic du forum [[http://​forum.ubuntu-fr.org/​viewtopic.php?​id=204074|[VOS SCRIPTS UTILES]]] et rajoutez un lien dans la page du wiki ci-dessus.+Une fois vos armes faites, proposez vos contributions sur le topic du forum [[https://​forum.ubuntu-fr.org/​viewtopic.php?​id=204074|[VOS SCRIPTS UTILES]]] et rajoutez un lien dans la page du wiki ci-dessus.
  
 ===== L'art d'​écrire un script ===== ===== L'art d'​écrire un script =====
Ligne 1445: Ligne 890:
 ===== Liens ===== ===== Liens =====
  
-  * (fr) http://​marcg.developpez.com/​ksh/​ : Pour ceux qui souhaitent aller plus loin dans la conception de script shell. +  * (fr) https://​marcg.developpez.com/​ksh/​ : Pour ceux qui souhaitent aller plus loin dans la conception de script shell. 
-  * (fr) [[http://​abs.traduc.org/​abs-fr/​|Guide avancé d'​écriture des scripts Bash]] : Un très bon tutoriel concernant la réalisation du script shell. C'est l'un des plus complets et les mieux détaillés disponibles en français. Il contient également [[http://​abs.traduc.org/​abs-5.3-fr/​apa.html|des exemples de script complets]], une [[http://​abs.traduc.org/​abs-5.3-fr/​apb.html|carte de référence]] (variables, tests...). Ce site est un site qui vaut réellement le détour pour tous ceux qui cherchent à créer des scripts complets en utilisant au mieux les performances du shell.+  * (fr) [[https://​abs.traduc.org/​abs-fr/​|Guide avancé d'​écriture des scripts Bash]] : Un très bon tutoriel concernant la réalisation du script shell. C'est l'un des plus complets et les mieux détaillés disponibles en français. Il contient également [[http://​abs.traduc.org/​abs-5.3-fr/​apa.html|des exemples de script complets]], une [[http://​abs.traduc.org/​abs-5.3-fr/​apb.html|carte de référence]] (variables, tests...). Ce site est un site qui vaut réellement le détour pour tous ceux qui cherchent à créer des scripts complets en utilisant au mieux les performances du shell.
   * (fr) https://​openclassrooms.com/​courses/​reprenez-le-controle-a-l-aide-de-linux : Un tutoriel très complet pour linux qui comporte quelques parties sur la réalisation de scripts bash.   * (fr) https://​openclassrooms.com/​courses/​reprenez-le-controle-a-l-aide-de-linux : Un tutoriel très complet pour linux qui comporte quelques parties sur la réalisation de scripts bash.
   * (en) [[http://​www.ibm.com/​developerworks/​library/​l-bash-parameters.html|Bash parameters and parameter expansions]]. En anglais mais contient de nombreux exemples concernant la gestion et l'​analyse des paramètres.   * (en) [[http://​www.ibm.com/​developerworks/​library/​l-bash-parameters.html|Bash parameters and parameter expansions]]. En anglais mais contient de nombreux exemples concernant la gestion et l'​analyse des paramètres.
   * (fr ) [[ftp://​ftp-developpez.com/​eric-sanchis/​IntroProgBash.pdf|Introduction à Bash]]   * (fr ) [[ftp://​ftp-developpez.com/​eric-sanchis/​IntroProgBash.pdf|Introduction à Bash]]
-  * (fr ) [[http://​www.scotchlinux.tuxfamily.org/​]] exemples de scripts bash, quelques trucs utiles ( fonctions, fonctions comme paramètres... ) +  * (fr ) [[http://​www.scotchlinux.tuxfamily.org/​]] exemples de scripts bash, quelques trucs utiles ( fonctions, fonctions comme paramètres... )
   * (en) [[https://​www.shellcheck.net/​]] Permet de corriger la syntaxe du script (parenthèse oubliée, graphie incorrecte d'une commande, un "​if"​ sans son "​fi",​ un "while sans son "​do"​ ou son "​done",​ etc...).   * (en) [[https://​www.shellcheck.net/​]] Permet de corriger la syntaxe du script (parenthèse oubliée, graphie incorrecte d'une commande, un "​if"​ sans son "​fi",​ un "while sans son "​do"​ ou son "​done",​ etc...).
  
  • tutoriel/script_shell.1645344023.txt.gz
  • Dernière modification: Le 20/02/2022, 09:00
  • par 88.170.129.244