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.
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 aenabled_fixes. Ad esempio il filemy_modfix.pyrisulterà in un ModFix chiamatomy_modfix.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 chiamatomy_modverrà caricato (e il modfix chiamatomy_modfixsarà 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 metodoModFix.update_mods_to_be_copied_list(), che si occupa di aggiungere automaticamente il mod alla listamods_to_be_copiedse necessario.Nel namespace del modulo MyModFix (dopo, all’esterno della neo creata classe) salvare un oggetto MyModFix in una variabile chiamata
to_be_registeredin questo modo:to_be_registered = MyModFix()
Questo passaggio è richiesto dal meccanismo di caricamento modfix.
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.
È 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’oggettoserver_instance.S, un’istanza della classeodk_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