Azioni specifiche per mod

L’architettura modulare di ODKSM rende facile implementare dei comportamenti specifici necessari a singoli mod, come ad esempio spostare un file di configurazione nella cartella giusta dopo aver installato un mod oppure linkare correttamente delle chiavi in posizioni inusuali. Questo viene realizzato tramite dei ModFix, dei moduli python plug&play.

Utilizzo

Abilitare un ModFix è semplice: basta inserirne il nome nella lista enabled_fixes.

Nota

Il nome di un ModFix è il nome del file del modulo (senza l’estensione .py), che può essere trovato nella cartella odk_servermanager\modfix (eccola, su github).

A questo punto, a seconda del modfix, potrebbero essere necessario aggiungere altri campi con i relativi valori nella sezione mod_fix_settings. In questa pagina si può trovare la documentazione riguardante i modfix attualmente implementati.

Linked vs copied

È importante notare la differenza tra mod copiati e linkati.

Normalmente, mod non collegati con un modfix vengono semplicemente linkati dentro la cartella linked_mod_folder_name; le cartelle di mod qui presenti, sono symlink che puntano alle relative cartelle mod, il che significa che il contenuto di queste cartelle di mod è quello originale: questi file sono gestiti direttametne da Steam e non dovrebbero essere toccati né da un utente né da un modfix. Questo è lo stesso comportamento che adotta la cartella !Workshop, dentro la cartella principale di Arma 3.

Quando è necessario operare cambiamenti all’interno di una cartella di un mod, il modfix dovrà invece copiare la cartella del mod con tutto il suo contenuto nella cartella copied_mod_folder_name. File e cartelle dentro quest’ultima possono essere modificati tranquillamente e sono distinti in ogni singola istanza.

Nota

Questo comportamento può essere forzato inserendo il nome di un mod nella lista mods_to_be_copied.

Avvertimento

Quando hanno a che fare con mod copiati, i modfix devono anche occuparsi di aggiornare la copia del mod dentro l’istanza server quando necessario. A seconda della struttura del mod e/o del modfix, il comportamento del tool al momento di aggiornare un mod copiato potrebbe cambiare. Assicurarsi di fare un backup di ogni file modificato manualmente dentro la cartella del mod copiato prima di aggiornare l’istanza server la prima volta, per sicurezza.

Implementare un ModFix

È relativamente facile implementare un ModFix. Alcuni esempi possono essere trovati nella cartella dei modfix.

  1. Prima di tutto creare un file python dentro la cartella odk_servermanager\modfix. Il nome del file sarà il nome del ModFix che dovrà essere aggiunto a enabled_fixes. Ad esempio il file my_modfix.py risulterà in un ModFix chiamato my_modfix.


  2. Dentro questo file, estendete la classe odk_servermanager.modfix.ModFix. Ad esempio:


    # file: odk_servermanager/modfix/my_modfix.py
    from odk_servermanager.modfix import ModFix
    
    
    class MyModFix(ModFix):
        """This is my wonderfull modfix"""
    
        name = "my_mod"  # this ModFix will be applied to the mod named 'my_mod'
    

    Il campo di classe name è obbligatorio: di default il modfix cercherà di usare quel campo per controllare se il modfix va applicato ad un mod. In questo caso, quando il mod chiamato my_mod verrà caricato (e il modfix chiamato my_modfix sarà abilitato!) il tool applicherà questo modfix.

    Se si desidera collegare modfix a mod in maniera diversa, si può fare override del metodo ModFix.does_apply_to_mod(). Potrebbe anche essere necessario fare override del metodo ModFix.update_mods_to_be_copied_list(), che si occupa di aggiungere automaticamente il mod alla lista mods_to_be_copied se necessario.


  3. Nel namespace del modulo MyModFix (dopo, all’esterno della neo creata classe) salvare un oggetto MyModFix in una variabile chiamata to_be_registered in questo modo:


    to_be_registered = MyModFix()
    

    Questo passaggio è richiesto dal meccanismo di caricamento modfix.


  4. Così facendo MyModFix verrà caricato, ma attualmente non farebbe nulla di utile. Introduciamo quindi gli hook modfix. Si tratta di metodi ereditati dalla classe ModFix e che sono impostati di default a None. È quindi necessario fare l’override del (o degli!) hook che meglio ricoprono le necessità del modfix e implementare lì le azioni specifiche di cui ha bisogno il mod. Più informazioni sugli hook possono essere trovate nella prossima sezione.


    Importante

    Ricordarsi di implementare entrambi gli stage: init e update.

  5. È una buona idea implementare una test suite per MyModFix. I test vanno dentro la cartella tests\modfixes, dove si trovano anche diversi esempi di test.

Hook dei ModFix

Ecco un esempio di un hook:

def hook_init_copy_replace(self, server_instance: ServerInstance, call_data: List[str]) -> None:
    """This is a hook that REPLACE the default COPY mod behavior during this instance INIT stage."""
    # do very complicated stuff here

Questo è un hook che RIMPIAZZA l’operazione di default di COPIA del mod durante lo stage di INIT.

Cominciamo con l’analizzarne gli argomenti:

server_instance: ServerInstance

Questo oggetto rappresenta l’istanza server attuale. È un oggetto della classe odk_servermanager.instance.ServerInstance. Può essere usato per modificare od ottenere informazioni riguardo l’istanza. Di particolare interesse è l’oggetto server_instance.S, un’istanza della classe odk_servermanager.settings.ServerInstanceSettings, che contiene tutte le impostazioni valida al momento nell’istanza.

call_data: List[str]

Questo viene raramente utilizzato. Si tratta di una lista che contiene, in ordine, lo stage attuale, l’attuale operazione e il nome del Mod.

Attualmente è possibile fare l’override di 12 hook. I loro nomi sono una combinazione di tre elementi:

hook^_[stage]_[operation]_[time]
stage:

init, update

operation:

copy, link

time:

pre, post, replace

stage: init

Tutti gli hook in questo stage vengono attivati durante la prima volta che un tool viene eseguito per una istanza server.

stage: update

Tutti gli hook in questo stage vengono attivati quando la cartella dell’istanza server è già presente e il tool viene attivato.

operation: copy

Questi hook si attivano se il mod è copiato.

operation: link

Questi hook si attivano se il mod è linkato.

time: pre

Questi hook si attivano prima della operation designata. La operation di default viene comunque eseguita.

time: post

Questi hook si attivano dopo della operation designata. La operation di default viene comunque eseguita.

time: replace

Questi hook rimpiazzato la operation di default. Pre e Post hook possono comunque venir chiamati intorno a questo hook replace.

Suggerimento

Se si ha bisogno di un hook che rimpiazzi una operation senza far nulla (ad esempio per evitare che avvenga l’update di default di un mod copiato), fare l’override dell’hook hook_update_copy_replace e inserire soltanto l’istruzione pass per non fargli far nulla, in questo modo:

def hook_update_copy_replace(server_instance, call_data):
    pass