[mod] Empyrion Scripting Mod

Discussion in 'Empyrion API' started by ASTIC, May 25, 2019.

Tags:
  1. ASTIC

    ASTIC Rear Admiral

    Joined:
    Dec 11, 2016
    Messages:
    1,094
    Likes Received:
    735
    @Preston SaveGameErrors/Exceptions kannst um im Logfile des Playfields sehen - aber ich versuche mal da was einfacheres ein zu bauen
     
    #121
  2. Preston

    Preston Commander

    Joined:
    Jul 6, 2017
    Messages:
    124
    Likes Received:
    25
    I do something wrong with the IScriptModData rootObject.
    The .dll calling savegamescript:
    Code:
    public static void Main(IScriptModData rootObject){
            //Scripts.CpuBoxFill.Run(rootObject);           // reads item requests from vessels and try to refill it (much logic/security conditions)
            //Scripts.CpuBoxPurge.Run(rootObject);          // gather all items from defined containers/vessels (much logic/security conditions)
            //Scripts.CpuBoxSort.Run(rootObject);           // reads levels and items needs and try to preserve the item count for specified containers  
            //Scripts.CpuStatBox.Run(rootObject);           // draws container fill levels
            Scripts.CpuStatCpu.Run(rootObject);           // draws processor device health information
            //Scripts.CpuStatDev.Run(rootObject);           // draws defective devices
            //Scripts.CpuStatDock.Run(rootObject);          // draws docked vessel data
            //Scripts.CpuStatL.Run(rootObject);             // draws information overview for bigger displays
            //Scripts.CpuStatS.Run(rootObject);             // draws compact information overview for smaller displays
            //Scripts.CpuStatThr.Run(rootObject);           // draws thruster health information
            //Scripts.CpuStatWpn.Run(rootObject);           // draws weapon health information
            //Scripts.CpuStatHll.Run(rootObject);           // draws a structure damage overview scheme
        }
    
        //Scripts.CpuStatCpu.Run(CsRoot,E);
        Scripts.CpuStatHll.Run(CsRoot,E);
    
    The playfield log shows no compiler error and this script is running (partly). The call-version out of Main with direct usage of the fields "CsRoot" und "E" works perfectly fine. The .dll functions do what they should.

    But the Main-method version using the rootObject does simply nothing. No Lcd output and also no visible exception or failure at all.

    The rootObject is .dll-internal split into the known fields:
    Code:
    private static IScriptModData root = null;
    private static ICsScriptFunctions CsRoot = null;
    private static IEntityData E = null;
    private static IPlayfieldData P = null;
    
    private static void Init(IScriptModData rootObject)
            {
                if (root == null)
                {
                    root = rootObject;
                    CsRoot = rootObject.CsRoot;
                    E = rootObject.E;
                    P = rootObject.P;
                    if (rootObject is IScriptSaveGameRootData data) { ItemGroups.SetFileRootPath(Path.Combine(data.MainScriptPath, "..")); }
                }
            }
    
    and used like this:

    Code:
    /....
    public static void Run(IScriptModData rootObject)
    {
          Init(rootObject);
          // without structure powered and without "processing device" the scrip should "sleep"
          IBlockData[] deviceProcessors = CsRoot.Devices(E.S, sProcessorName);
          if (E.S.IsPowerd && deviceProcessors != null && deviceProcessors.Count() > 0)
                 {
                           //....
    
    I assume that there are runtime-exceptions. Probably null-pointer ones. But without the savegame logging I will not identify them. Thanks for adding a log function.
     
    #122
  3. tachyon

    tachyon Commander

    Joined:
    Aug 12, 2015
    Messages:
    92
    Likes Received:
    134
    Es wäre cool, wenn man den Debuglevel in der Console einstellen könnte. Und die Ausgaben dann dort erfolgen würden. Das API würde beides hergeben.
     
    #123
  4. ASTIC

    ASTIC Rear Admiral

    Joined:
    Dec 11, 2016
    Messages:
    1,094
    Likes Received:
    735
    Version 5.9.1: Log SaveGameScriptsErrors in file
    upload_2020-8-17_12-0-25.png

    all you need is
    "ScriptTrackingError": true,
    in the Configuration.json file

    PS: Fehler in der Console auszugeben hat das "Problem" das dies über das Netz geht und auch Spieler erreicht die keine Berechtigung haben dies zu sehen, da z.B. SafeGameScripte ja dem ServerAdmin vorbehalten sind welcher noch über dem InGameAdmin steht
     
    #124
  5. Preston

    Preston Commander

    Joined:
    Jul 6, 2017
    Messages:
    124
    Likes Received:
    25
    Does no file mean "no error"?:

    [​IMG]
    [​IMG]
    [​IMG]
     
    #125
  6. ASTIC

    ASTIC Rear Admiral

    Joined:
    Dec 11, 2016
    Messages:
    1,094
    Likes Received:
    735
    Yep
    Code:
    ...
    finally
    {
        if (!string.IsNullOrEmpty(exceptionMessage))
        {
            Log?.Invoke($"C# Run [{root.ScriptId}]:{exceptionMessage}", LogLevel.Error);
    
            if (EmpyrionScripting.Configuration.Current.ScriptTrackingError)
            {
                File.WriteAllText(root is ScriptSaveGameRootData saveGameRoot
                    ? EmpyrionScripting.GetTrackingFileName(saveGameRoot)
                    : EmpyrionScripting.GetTrackingFileName(root.E.GetCurrent(), root.Script.GetHashCode().ToString()) + ".error",
                    exceptionMessage);
            }
        }
    }
    
     
    #126
  7. Preston

    Preston Commander

    Joined:
    Jul 6, 2017
    Messages:
    124
    Likes Received:
    25
    Hmmmm, then: Houston, we have a problem. ;)

    The script outputs nothing to the lcds if it uses the IScriptModData instead of CsRoot.
    With CsRoot without "Main" the script works fine.
    If no Exception is thrown, what could be the reason that the script does nothing but the Mod Runtine "thinks" all is fine?

    I tried to simple-access a Lcd and I try also to use "Console" to generate a step by step log.
    But nothing. All outputs I know seem to have the same problem. I think because they are all based on the rootObject while within Main.

    I will later write a simple .dll with rootObject to isolate the problem.
    Below is my actual .dll if some feels giddy to have a look. :)
     

    Attached Files:

    #127
  8. Preston

    Preston Commander

    Joined:
    Jul 6, 2017
    Messages:
    124
    Likes Received:
    25
    I wrote a simple outputting test .dll using lcd access and console. The concole outputs should go to the right lcd. The lcd output should go to the left lcd. Errors should go to the right lcd or script tracking.
    But "nothing" happens:
    Code:
    using System;
    using System.Linq;
    using Eleon.Modding;
    using EmpyrionScripting.Interface;
    
    namespace CallTestLib
    {
        public static class TestClass
        {
            public static void Run(IScriptModData rootObject)
            {
    
                rootObject.Console.WriteLine("ConsoleOut01: " + DateTime.Now.ToString());
    
                ICsScriptFunctions CsRoot = rootObject.CsRoot;
                IEntityData E = rootObject.E;
    
                rootObject.Console.WriteLine("ConsoleOut02: " + DateTime.Now.ToString());
    
                IBlockData[] deviceProcessors = CsRoot.Devices(E.S, "C#:*");
                if (E.S.IsPowerd && deviceProcessors != null && deviceProcessors.Count() > 0)
                {
                    rootObject.Console.WriteLine("ConsoleOut03: " + DateTime.Now.ToString());
    
                    ILcd outputLcd = CsRoot.GetDevices<ILcd>(CsRoot.Devices(E.S, "DispCpuState")).FirstOrDefault();
    
                    outputLcd.SetText("DeviceOut01: " + DateTime.Now.ToString());
    
    
                    rootObject.Console.WriteLine("ConsoleOut04: " + DateTime.Now.ToString());
                }
            }
        }
    }
    
    [​IMG]

    [​IMG]
     

    Attached Files:

    #128
  9. ASTIC

    ASTIC Rear Admiral

    Joined:
    Dec 11, 2016
    Messages:
    1,094
    Likes Received:
    735
    I
    Ich schaue mir das mal an.
    Bei SafeGameScripten ist es zur Zeit so, das diese für die Struktur aufgerufen werden und nicht an ein LCD gekoppelt sind, somit gehen Console.Write Befehle ins Leere und mann muss sie selber auf ein LCD leiten.
    Ich werde heute das noch einbauen das solche Ausgaben auf ein LCD mit dem gleichen Namen wie das SaveganeScript ausgegeben werden wenn ein solches existiert - also z.B. CargoScript.cs -> CargoScript als LCD Name
     
    #129
  10. Preston

    Preston Commander

    Joined:
    Jul 6, 2017
    Messages:
    124
    Likes Received:
    25
    Ich habe schon vermutet, dass "Console.WriteLine" nicht weiß wohin mit der Ausgabe.
    Aber das "selber auf ein LCD leiten" versucht meine CallTestLib.dll ja auch. Das funktioniert ja auch nicht.

    Wenn ich statt dem IScriptModData Objekt das ICsScriptFunctions Objekt (außerhalb von Main) an meine Lib übergebe, erreiche ich mit "GetDevices" auch die Lcds wieder.

    Irgendwas läuft da mit dem an die "Main" übergebenen Objekt schief.
    Wie macht denn der Script Compiler aus dem IScriptModData Objekt das ICsScriptFunctions Objekt "CsRoot", welches ingame zur Verfügung steht? Vielleicht erzeuge ich mein internes CsRoot-Objekt falsch?
     
    #130
    Last edited: Aug 18, 2020
  11. ASTIC

    ASTIC Rear Admiral

    Joined:
    Dec 11, 2016
    Messages:
    1,094
    Likes Received:
    735
    Version 5.9.2:
    - SaveGameScripte: LCD output on LCD Named as filename without extension eg: "C:\steamcmd\empyrion\Saves\Games\Default\Mods\EmpyrionScripting\Scripts\CargoTeleporter.cs" -> LCD name: CargoTeleporter.....
    - CsRoot.Root added
    - Exception and output on target lcd


    upload_2020-8-18_14-58-5.png

    @Preston this is with your DLL ;-)
     
    #131
    Preston likes this.
  12. Preston

    Preston Commander

    Joined:
    Jul 6, 2017
    Messages:
    124
    Likes Received:
    25
    Mir kamen die Texte doch gleich so bekannt vor. :)

    Funktioniert super, jetzt läuft alles, danke
    [​IMG]
     
    #132
    ASTIC likes this.
  13. Preston

    Preston Commander

    Joined:
    Jul 6, 2017
    Messages:
    124
    Likes Received:
    25
    I'm really sorry but I seem to have the talent to find unusual issues. -.-

    I try to write a adaption of your floor-script and struggled about a block position problem.
    My loops over the structure block positions between "E.S.MinPos" and "E.S.MaxPos" do not find any valid block.

    Therefore I write a simple output test to compare the real block positions with the areas which do "MinPos" and "MaxPos" return:
    Code:
    //.........
    public static void Run(IScriptModData root)
                {
                    //Script Content Data
                    ICsScriptFunctions CsRoot = root.CsRoot;
                    IEntityData E = root.E;
    
                    root.Console.WriteLine("Structure: " + E.Name);
                    root.Console.WriteLine("MinPos: " + E.S.MinPos);
                    root.Console.WriteLine("MaxPos: " + E.S.MaxPos);
                    root.Console.WriteLine("LcdPos: " + CsRoot.Devices(E.S, "EgsEsExtension").FirstOrDefault().Position);
    
                    //.........
    
    This is the result:

    [​IMG]

    As you can see in the lcd output and although in the di-display the lcd is out of the limits which "MinPos" and "MaxPos" return.
    From the code snippet I would say the underlying structure Object should be the same.
    And therefore I do not understand why the display can be outside the limits.
     
    #133
  14. ASTIC

    ASTIC Rear Admiral

    Joined:
    Dec 11, 2016
    Messages:
    1,094
    Likes Received:
    735
    Min/Max bezieht sich (leider aus historischen Gründen) auf einen virtuellen Mittelpunkt x: 0 y:128 z:0 d.h. du musst auf das y noch 128 drauf addieren um die "echte" Blockposition zu bekommen :-(
     
    #134
  15. Preston

    Preston Commander

    Joined:
    Jul 6, 2017
    Messages:
    124
    Likes Received:
    25
    Ich nehme mal an das "Y" die Höhe ist? nicht "Z"?
    Wenn ich mir die Positionen so anschaue, würde ich sagen Min/Max hat "recht" und die tatsächliche Position ist falsch.
    Meine Basis ist keine 141 Blöcke hoch. Aber meine Basis ist höher als breit und tief.
    Die Werte von Min/Max sind realistischer....hmmmm.
     
    #135
  16. ASTIC

    ASTIC Rear Admiral

    Joined:
    Dec 11, 2016
    Messages:
    1,094
    Likes Received:
    735
    Genau X/Z ist die horizontale Ebene und Y die Höhe ... die 128 kommen aus den grauen Vorzeiten von Empyrion und sind leider nie "refactored" worden so das man einen "normalen" Nullpunkt gehabt hätte :-(
     
    #136
  17. me777

    me777 Commander

    Joined:
    Aug 18, 2020
    Messages:
    406
    Likes Received:
    139
    Hallo,
    Ich habe Schwierigkeiten auf einem Server Savegame Scripts zum laufen zu bekommen... (incl. dem AcriveRadar Script)
    Folgende Fragen hätte ich da:

    Wo ligt bei einem Server die Config?
    Gibt es eine Config Option das ganze einzuschalten?
    Wie schalte ich Fehlermeldungen ein?
    Muss ich den Server neu starten wenn ich etwas an einem Script ändere?

    Und noch eine Frage zum Scripting selber: kann ich irgendwie rausfinden ob ein Konstructor/Lebensmittel-Prozessor grade etwas tut?

    Danke für das Coole Mod und jede Hilfe!
    Michael
     
    #137
  18. Preston

    Preston Commander

    Joined:
    Jul 6, 2017
    Messages:
    124
    Likes Received:
    25
    Im savegamepath, abhängig von deiner Servereinstellung, liegen alle für dich als "Anwender" relevanten Dateien.
    Configs, Permissions, Scripte, Logs, usw.
    z.B.: D:\GameServerBackUps\Empyrion\Games\(savegamename)\Mods\EmpyrionScripting

    Mit den Initialwerten in Configuration.json läuft alles.

    Configuration.json --> "ScriptTracking" und "ScriptErrorTracking" auf "true"
    Dann enstehen im Savegamepath neue dateien.
    Die Ingame Fehlermeldungen auf den Lcds sind aber auch ohne diese Einstellung "an".

    Jein :)
    Die Mod überwacht alle Dateien und "startet sich automatisch neu" wenn sich eine Datei ändert.
    Allerdings scheint Eleon mit dem Update 1.x ein paar Instabilitäten eingebaut zu haben.
    Bei mir hängt sich die Mod gelegentlich bei Änderungen an den Dateien auf und ich muss den Server dann doch neu starten.

    Soweit ich weiß ist das Interface für die Konstruktoren noch nicht fertig.
     
    #138
    ASTIC likes this.
  19. me777

    me777 Commander

    Joined:
    Aug 18, 2020
    Messages:
    406
    Likes Received:
    139
    OK, ich hab jetzt die ersten savegame scripts laufen und gleich neue Fragen:

    Ist der Aktualisierungs-Intervall fest (scheint immer 10s zu sein) oder kann der schwanken?
    Kann ich irgendwie mit der Zeit rechnen? sowas wie vergangene Sekunden seit X?
    Läuft das Script auf dem Server weiter wenn ich offline bin?
     
    #139
  20. Preston

    Preston Commander

    Joined:
    Jul 6, 2017
    Messages:
    124
    Likes Received:
    25
    Der Intervall steht standardmäßig auf 10000ms und kann in der Configuration.json verändert werden.
    Da die Scripts den Server nicht behindern sollen, werden sie im Backgroundworker verarbeitet, welcher nicht deterministisch ist.
    Es können also auch mal 11000ms werden. Wenn du es genauer brauchst, muss du mit der C# Klasse "DateTime" arbeiten.

    Das Script läuft Playfield bezogen. Abhängig von der Einstellung deines Server(leer-Playfield-Verarbeitung) läuft das Script also weiter.
     
    #140

Share This Page