public void ReadBlockMappingFile(string blockMappingFile, IModApi modApi)
        {
            try
            {
                BlockIdMapping = modApi?.Application.GetBlockAndItemMapping();
                if (BlockIdMapping?.Count == 0)
                {
                    Log($"GetBlockAndItemMapping empty try self", LogLevel.Message);
                    BlockIdMapping = Parse.ReadBlockMapping(blockMappingFile);
                }
                else
                {
                    Log($"ReadBlockMappingFile: BlockIdMapping API:[{BlockIdMapping?.Count}]", LogLevel.Message);
                }
            }
            catch (Exception error)
            {
                Log($"GetBlockAndItemMapping: {error}", LogLevel.Error);
                BlockIdMapping = Parse.ReadBlockMapping(blockMappingFile);
            }

            try
            {
                IdBlockMapping = BlockIdMapping.ToDictionary(I => I.Value, I => I.Key);
            }
            catch (Exception error)
            {
                IdBlockMapping = new Dictionary <int, string>();
                Log($"IdBlockMapping: {error}", LogLevel.Error);
            }
        }
Esempio n. 2
0
 public BFAV226Integrator()
 {
     if (ModEntry.SHelper.ModRegistry.IsLoaded("Paritee.BetterFarmAnimalVariety"))
     {
         BFAVApi = ModEntry.SHelper.ModRegistry.GetApi <IModApi>("Paritee.BetterFarmAnimalVariety");
         RegisterBFAVAnimals();
     }
 }
Esempio n. 3
0
        void IMod.Init(IModApi modAPI)
        {
            modApi            = modAPI;
            modApi.GameEvent += EventGame;

            modApi.Application.OnPlayfieldLoaded    += OnLoadedPlayfield;
            modApi.Application.OnPlayfieldUnloading += OnUnLoadedPlayfield;
            modApi.Application.GameEntered          += EnteredGame;
            modApi.Application.Update += UpdateAll;
            modApi.Log("ModApi Loaded");
            Console.WriteLine("ModApi Loaded");
        }
Esempio n. 4
0
        void IMod.Init(IModApi modAPI)
        {
            this.APIInitialized = true;
            this.GameAPI        = modAPI;

            Logger.logFunction = modAPI.Log;

            RunInitialize();

            this.ChatCommandManager             = new ChatCommandManager(this.ChatCommands);
            modAPI.Application.ChatMessageSent += SimpleMod_ProcessChatCommands;
        }
        void IMod.Init(IModApi modAPI)
        {
            _modApi = modAPI;
#if DEBUG
            _nlogMemoryTarget = new NlogMemoryTarget("ExampleMod", NLogLevel.Trace, NLogLevel.Fatal);
#else
            _nlogMemoryTarget = new NlogMemoryTarget("ExampleMod", NLogLevel.Trace, NLogLevel.Fatal);
#endif
            _nlogMemoryTarget.OnLog += _nlogMemoryTarget_OnLog;

            _modApi.Application.OnPlayfieldLoaded += Application_OnPlayfieldLoaded;
        }
Esempio n. 6
0
        const int BatteryCheckInterval = 25000;                 //in MS


        public void Init(IModApi modAPI)
        {
            mAPI = modAPI;

            mAPI.Log("SolarHelperNewAPI: Init called.");

            mAPI.GameEvent += OnGameEvent;
            mAPI.Application.OnPlayfieldLoaded   += OnPlayFieldLoaded;
            mAPI.Application.OnPlayfieldUnloaded += OnPlayFieldUnLoaded;
            mAPI.Application.GameEntered         += OnGameEntered;

            mBatTimer = new Timer(BatteryCheckInterval);

            mBatTimer.Elapsed  += OnBatteryTimer;
            mBatTimer.AutoReset = true;
            mBatTimer.Start();
        }
Esempio n. 7
0
        public void Init(IModApi modAPI)
        {
            ModApi = modAPI;

            ModApi.Log("EmpyrionScripting Mod started: IModApi");
            try
            {
                SetupHandlebarsComponent();

                SaveGameModPath = Path.Combine(ModApi.Application?.GetPathFor(AppFolder.SaveGame), "Mods", EmpyrionConfiguration.ModName);
                ModApi.Application.GameEntered += Application_GameEntered;

                LoadConfiguration();
                SaveGamesScripts = new SaveGamesScripts(modAPI)
                {
                    SaveGameModPath = SaveGameModPath
                };
                SaveGamesScripts.ReadSaveGamesScripts();

                TaskTools.Log = ModApi.LogError;
                StaticCsCompiler.CsCompiler.Log = Log;

                CsCompiler = new CsCompiler.CsCompiler(SaveGameModPath);
                CsCompiler.ConfigurationChanged += CsCompiler_ConfigurationChanged;

                ModApi.Application.OnPlayfieldLoaded    += Application_OnPlayfieldLoaded;
                ModApi.Application.OnPlayfieldUnloading += Application_OnPlayfieldUnloading;

                StopScriptsEvent += (S, E) =>
                {
                    PlayfieldData?.Values.ForEach(P =>
                    {
                        ModApi.Log($"StopScriptsEvent: ({P.PlayfieldName}) {(P.PauseScripts ? "always stopped" : "scripts running")}");
                        P.PauseScripts = true;
                    });
                };

                StartAllScriptsForPlayfieldServer();
            }
            catch (Exception error)
            {
                ModApi.LogError($"EmpyrionScripting Mod init finish: {error}");
            }

            ModApi.Log("EmpyrionScripting Mod init finish");
        }
Esempio n. 8
0
        public void Init(IModApi modAPI)
        {
            mAPI = modAPI;

            mAPI.Log("LCDMagicNewAPI: Init called.");

            mAPI.GameEvent += OnGameEvent;
            mAPI.Application.OnPlayfieldLoaded   += OnPlayFieldLoaded;
            mAPI.Application.OnPlayfieldUnloaded += OnPlayFieldUnLoaded;
            mAPI.Application.GameEntered         += OnGameEntered;

            LoadConstants();

            StartTimer(ref mLCDScanTimer, "LCDScanInterval", OnLCDScanTimer);
            StartTimer(ref mContainerTimer, "ContainerUpdateInterval", OnContainerTimer);
            StartTimer(ref mAmmoTimer, "AmmoUpdateInterval", OnAmmoTimer);
            StartTimer(ref mFridgeTimer, "FridgeUpdateInterval", OnFridgeTimer);
            StartTimer(ref mSpecialTimer, "SpecialUpdateInterval", OnSpecialTimer);
        }
        public void Init(IModApi modAPI)
        {
            ModApi = modAPI;

            ModApi.Log("EmpyrionScripting Mod started: IModApi");
            try
            {
                SetupHandlebarsComponent();

                Localization    = new Localization(ModApi.Application?.GetPathFor(AppFolder.Content));
                ItemInfos       = new ItemInfos(ModApi.Application?.GetPathFor(AppFolder.Content), Localization);
                SaveGameModPath = Path.Combine(ModApi.Application?.GetPathFor(AppFolder.SaveGame), "Mods", EmpyrionConfiguration.ModName);

                LoadConfiguration();
                SaveGamesScripts = new SaveGamesScripts(modAPI)
                {
                    SaveGameModPath = SaveGameModPath
                };
                SaveGamesScripts.ReadSaveGamesScripts();

                TaskTools.Log = ModApi.LogError;

                ModApi.Application.OnPlayfieldLoaded   += Application_OnPlayfieldLoaded;
                ModApi.Application.OnPlayfieldUnloaded += Application_OnPlayfieldUnloaded;

                StopScriptsEvent += (S, E) =>
                {
                    ModApi.Log($"StopScriptsEvent: {(PauseScripts ? "always stopped" : "scripts running")}");
                    PauseScripts = true;
                };

                StartAllScriptsForPlayfieldServer();
            }
            catch (Exception error)
            {
                ModApi.LogError($"EmpyrionScripting Mod init finish: {error}");
            }

            ModApi.Log("EmpyrionScripting Mod init finish");
        }
Esempio n. 10
0
        //check for newly placed or removed lcds
        //the timer for this should be biggish as all this is expensive
        internal void LCDScan(bool bCheckBlockDestroyed, IModApi api, float blockDist)
        {
            if (bCheckBlockDestroyed)
            {
                CheckAssociatedLCDs(api);
            }

            if (mStruct == null)
            {
                api.Log("Null struct in player struct list!");
                return;
            }
            if (!mStruct.IsReady)
            {
                api.Log("Struct: " + mStruct + " not ready...");
                return;
            }
            if (!mStruct.IsPowered)
            {
                //api.Log("Struct: " + mStruct + " not powered...");
                return;
            }

            /*
             * string	[]dTypeNames	=mStruct.GetDeviceTypeNames();
             * foreach(string dname in dTypeNames)
             * {
             *      api.Log("Device: " + dname);
             * }*/

            IDevicePosList idplAmmo      = mStruct.GetDevices("AmmoCntr");
            IDevicePosList idplContainer = mStruct.GetDevices("Container");
            IDevicePosList idplFridge    = mStruct.GetDevices("Fridge");
            IDevicePosList idplHarvest   = mStruct.GetDevices("HarvestCntr");

            CheckLCD(api, idplAmmo, idplContainer, idplFridge, idplHarvest, blockDist);
        }
Esempio n. 11
0
        public void Init(IModApi modAPI)
        {
            ModAPI = modAPI;

            Interlocked.Increment(ref inst);

            ModAPI.Log($"LoadMod(Init)[{inst}]");

            try
            {
                if (mSingleIModInstance != null)
                {
                    mSingleIModInstance.Init(ModAPI);
                }
                else
                {
                    IMods.ForEach(M => M.Init(ModAPI));
                }
            }
            catch (Exception error)
            {
                ModAPI.LogError($"LoadMod(Init): error : {error}");
            }
        }
Esempio n. 12
0
        void CheckLCD(IModApi api, IDevicePosList ammo, IDevicePosList container,
                      IDevicePosList fridge, IDevicePosList harvest, float blockScanDist)
        {
            IDevicePosList idpl = mStruct.GetDevices("LCD");

            for (int i = 0; i < idpl.Count; i++)
            {
                VectorInt3 pos = idpl.GetAt(i);

                ILcd lcd = mStruct.GetDevice <ILcd>(pos);

                if (mAmmoLCD.ContainsValue(lcd))
                {
                    continue;                           //already in use
                }
                if (mContainerLCD.ContainsValue(lcd))
                {
                    continue;                           //already in use
                }
                if (mFridgeLCD.ContainsValue(lcd))
                {
                    continue;                           //already in use
                }
                if (mHarvestLCD.ContainsValue(lcd))
                {
                    continue;                           //already in use
                }

                api.Log("Unattached LCD Device at pos: " + pos);

                //find the closest device within BlockScanDistance
                float      blockDist = blockScanDist;
                float      bestDist  = float.MaxValue;
                VectorInt3 bestPos   = new VectorInt3(-1, -1, -1);
                int        bestType  = -1;
                IDevice    assoc     = null;

                for (int j = 0; j < ammo.Count; j++)
                {
                    VectorInt3 pos2 = ammo.GetAt(j);

                    float dist = VecDistance(pos, pos2);
                    if (dist < blockDist && dist < bestDist)
                    {
                        assoc    = mStruct.GetDevice <IContainer>(pos2);
                        bestDist = dist;
                        bestType = 0;
                        bestPos  = pos2;
                    }
                }

                for (int j = 0; j < container.Count; j++)
                {
                    VectorInt3 pos2 = container.GetAt(j);

                    float dist = VecDistance(pos, pos2);
                    if (dist < blockDist && dist < bestDist)
                    {
                        assoc    = mStruct.GetDevice <IContainer>(pos2);
                        bestDist = dist;
                        bestType = 1;
                        bestPos  = pos2;
                    }
                }

                for (int j = 0; j < fridge.Count; j++)
                {
                    VectorInt3 pos2 = fridge.GetAt(j);

                    float dist = VecDistance(pos, pos2);
                    if (dist < blockDist && dist < bestDist)
                    {
                        assoc    = mStruct.GetDevice <IContainer>(pos2);
                        bestDist = dist;
                        bestType = 2;
                        bestPos  = pos2;
                    }
                }

                for (int j = 0; j < harvest.Count; j++)
                {
                    VectorInt3 pos2 = harvest.GetAt(j);

                    float dist = VecDistance(pos, pos2);
                    if (dist < blockDist && dist < bestDist)
                    {
                        assoc    = mStruct.GetDevice <IContainer>(pos2);
                        bestDist = dist;
                        bestType = 3;
                        bestPos  = pos2;
                    }
                }

                IBlock lcdBlock = mStruct.GetBlock(pos);

                if (assoc == null)
                {
                    api.Log("Null Assoc");

                    //maybe since this isn't near a device
                    //it can be used for fuel or something
                    CheckForSpecialLCD(lcdBlock, lcd);
                    continue;
                }

                if (!mDevicePositions.ContainsKey(lcd))
                {
                    mDevicePositions.Add(lcd, pos);
                }
                if (!mDevicePositions.ContainsKey(assoc))
                {
                    mDevicePositions.Add(assoc, bestPos);
                }

                IBlock devBlock = mStruct.GetBlock(bestPos);

                if (lcdBlock == null)
                {
                    api.Log("Null block for lcd!");
                }
                else
                {
                    if (mDeviceBlocks.ContainsKey(lcd))
                    {
                        api.Log("BadCleanup!  Device blocks already has lcd: " + lcd + "!!");
                    }
                    else
                    {
                        mDeviceBlocks.Add(lcd, lcdBlock);
                    }
                }

                if (devBlock == null)
                {
                    api.Log("Null block for device!");
                }
                else
                {
                    if (mDeviceBlocks.ContainsKey(assoc))
                    {
                        api.Log("BadCleanup!  Device blocks already has assoc: " + assoc + "!!");
                    }
                    else
                    {
                        mDeviceBlocks.Add(assoc, devBlock);
                    }
                }

                if (bestType == 0)
                {
                    api.Log("Ammo Assoc");
                    mAmmoLCD.Add(assoc as IContainer, lcd);
                }
                else if (bestType == 1)
                {
                    api.Log("Con Assoc");
                    mContainerLCD.Add(assoc as IContainer, lcd);
                }
                else if (bestType == 2)
                {
                    api.Log("Fridge Assoc");
                    mFridgeLCD.Add(assoc as IContainer, lcd);
                }
                else if (bestType == 3)
                {
                    api.Log("Harv Assoc");
                    mHarvestLCD.Add(assoc as IContainer, lcd);
                }
            }
        }
Esempio n. 13
0
 public SaveGamesScripts(IModApi modApi)
 {
     ModApi = modApi;
 }
Esempio n. 14
0
 public abstract void Initialize(IModApi api, ModGameAPI legacyApi);
        public void Init(IModApi modAPI)
        {
            ModAPI = modAPI;

            ModAPI.Network.RegisterReceiverForPlayfieldPackets(PlayfieldDataReceived);
        }
Esempio n. 16
0
        //normally called when a block is deleted
        void CheckAssociatedLCDs(IModApi api)
        {
            List <IDevice> toNuke = new List <IDevice>();

            //check ammo
            ConfirmStillThere(mAmmoLCD, toNuke);

            //check container
            ConfirmStillThere(mContainerLCD, toNuke);

            //check fridge
            ConfirmStillThere(mFridgeLCD, toNuke);

            //check harvest
            ConfirmStillThere(mHarvestLCD, toNuke);

            //check tanks
            ConfirmStillThere(mTankLCDs, toNuke);

            //check farm
            ConfirmStillThere(mFarmLCDs, toNuke);

            if (toNuke.Count <= 0)
            {
                return;
            }

            api.Log("CheckAssociatedLCDs found " + toNuke.Count + " nuked items...");

            for (int i = 0; i < toNuke.Count; i++)
            {
                if (toNuke[i] is ILcd)
                {
                    ILcd lcd = toNuke[i] as ILcd;

                    NukeLCD(mAmmoLCD, lcd);
                    NukeLCD(mContainerLCD, lcd);
                    NukeLCD(mFridgeLCD, lcd);
                    NukeLCD(mHarvestLCD, lcd);
                    NukeLCD(mTankLCDs, lcd);
                    NukeLCD(mFarmLCDs, lcd);
                }
                else if (toNuke[i] is IContainer)
                {
                    IContainer con = toNuke[i] as IContainer;
                    ILcd       lcd = null;

                    if (mAmmoLCD.ContainsKey(con))
                    {
                        lcd = mAmmoLCD[con];
                        mAmmoLCD.Remove(con);
                    }
                    if (mContainerLCD.ContainsKey(con))
                    {
                        lcd = mContainerLCD[con];
                        mContainerLCD.Remove(con);
                    }
                    if (mFridgeLCD.ContainsKey(con))
                    {
                        lcd = mFridgeLCD[con];
                        mFridgeLCD.Remove(con);
                    }
                    if (mHarvestLCD.ContainsKey(con))
                    {
                        lcd = mHarvestLCD[con];
                        mHarvestLCD.Remove(con);
                    }

                    //make sure if one device is gone
                    //to remove the associated stuff as well
                    if (lcd != null)
                    {
                        mDevicePositions.Remove(lcd);
                        mDeviceBlocks.Remove(lcd);
                        mDevicePositions.Remove(con);
                        mDeviceBlocks.Remove(con);
                    }
                }
            }
        }
Esempio n. 17
0
 public void Init(IModApi modAPI)
 {
     modApi = modAPI;
 }
        public void ReadConfigEcf(string contentPath, string activeScenario, string blockMappingFile, IModApi modApi)
        {
            ContentPath         = contentPath;
            ScenarioContentPath = string.IsNullOrEmpty(activeScenario) ? null : Path.Combine(contentPath, "Scenarios", activeScenario, "Content");

            Log($"EmpyrionScripting ReadConfigEcf: ContentPath:{contentPath} Scenario:{activeScenario} -> {ScenarioContentPath}", LogLevel.Message);

            var timer = Stopwatch.StartNew();

            ReadBlockMappingFile(blockMappingFile, modApi);
            ReadEcfFiles();
            MergeEcfFiles();
            BuildIdAndNameAccess();
            FlatEcfConfigData();
            CalcBlockRessources();
            timer.Stop();

            if (EmpyrionScripting.Configuration?.Current?.LogLevel == LogLevel.Debug)
            {
                BlockIdMapping.ForEach(B => Log($"ReadBlockMappingFile: '{B.Key}' -> {B.Value}]", LogLevel.Debug));
                Templates_Ecf.Blocks.ForEach(B => Log($"Templates_Ecf.Blocks: '{B.Name}[{B.Values?.FirstOrDefault(A => A.Key == "Id").Value}] '{B.Values?.FirstOrDefault(A => A.Key == "Name").Value}'", LogLevel.Debug));
                BlocksConfig_Ecf.Blocks.ForEach(B => Log($"BlocksConfig_Ecf.Blocks: '{B.Name}[{B.Values?.FirstOrDefault(A => A.Key == "Id").Value}] '{B.Values?.FirstOrDefault(A => A.Key == "Name").Value}'", LogLevel.Debug));
                ItemsConfig_Ecf.Blocks.ForEach(B => Log($"ItemsConfig_Ecf.Blocks: '{B.Name}[{B.Values?.FirstOrDefault(A => A.Key == "Id").Value}] '{B.Values?.FirstOrDefault(A => A.Key == "Name").Value}'", LogLevel.Debug));
                Configuration_Ecf.Blocks.ForEach(B => Log($"Configuration_Ecf.Blocks: '{B.Name}[{B.Values?.FirstOrDefault(A => A.Key == "Id").Value}] '{B.Values?.FirstOrDefault(A => A.Key == "Name").Value}'", LogLevel.Debug));
                Flat_Config_Ecf.Blocks.ForEach(B => Log($"Flat_Config_Ecf.Blocks: '{B.Name}[{B.Values?.FirstOrDefault(A => A.Key == "Id").Value}] '{B.Values?.FirstOrDefault(A => A.Key == "Name").Value}'", LogLevel.Debug));
                FlatConfigBlockById.ForEach(B => Log($"FlatConfigBlockById: '{B.Key}' -> {B.Value?.Values?.FirstOrDefault(A => A.Key == "Name").Value}]", LogLevel.Debug));
                FlatConfigBlockByName.ForEach(B => Log($"FlatConfigBlockByName: '{B.Key}' -> {B.Value?.Values?.FirstOrDefault(A => A.Key == "Name").Value}]", LogLevel.Debug));
                ResourcesForBlockById.ForEach(B => Log($"ResourcesForBlockById: [{B.Key}] {(EmpyrionScripting.ConfigEcfAccess.FlatConfigBlockById.TryGetValue(B.Key, out var data) ? data.Values["Name"] : "")} -> {B.Value.Aggregate("", (r, i) => $"{r}\n{i.Value}: [{i.Key}] {(EmpyrionScripting.ConfigEcfAccess.FlatConfigBlockById.TryGetValue(i.Key, out var data) ? data.Values["Name"] : "")}")}", LogLevel.Message));
                ParentBlockName.ForEach(B => Log($"ParentBlockName: {B.Key} -> {B.Value}", LogLevel.Debug));
            }

            Log($"EmpyrionScripting Configuration_Ecf: #{Configuration_Ecf?.Blocks?.Count} BlockById: #{ConfigBlockById?.Count} BlockByName: #{ConfigBlockByName?.Count} ParentBlockNames: #{ParentBlockName.Count} BlockIdMapping:[{BlockIdMapping?.Count}] {blockMappingFile} takes:{timer.Elapsed}", LogLevel.Message);
        }
Esempio n. 19
0
        /// <summary>
        /// Called by Empyrion when the mod is first loaded.
        /// </summary>
        /// <param name="modAPI">Provides access to the Empyrion game state.</param>
        public void Init(IModApi modAPI)
        {
            EmpyrionApi = modAPI;
            Application = modAPI.Application;

            Log.LogReceived += Log_LogReceived;

            if (this.NetworkServerHost == null)
            {
                try
                {
                    this.NetworkServerHost = new ModServerHost();
                    this.NetworkServerHost.Server.BindEndPoints.Add(new IPEndPoint(IPAddress.Loopback, Connection.DefaultPort));
                    this.NetworkServerHost.Server.Start();
                } catch (Exception ex)
                {
                    Log.Warn("Failed to create DCE server. Remote connections will not be possible from client systems. " + ex.Message);
                    this.NetworkServerHost = null;
                }
            }

            if (this.GameStateProcessor == null)
            {
                this.GameStateProcessor = new GameStateProcessor();
            }

            Application.OnPlayfieldLoaded    += Application_OnPlayfieldLoaded;
            Application.OnPlayfieldUnloading += Application_OnPlayfieldUnloading;

            string contentPath       = Application.GetPathFor(AppFolder.Content);
            string localizationPath  = Path.Combine(contentPath, @"Extras\Localization.csv");
            string exampleConfigPath = Path.Combine(contentPath, @"Configuration\Config_Example.ecf");
            string customConfigPath  = Path.Combine(contentPath, @"Configuration\Config.ecf");

            try
            {
                if (Localization == null)
                {
                    Localization = new Localization(localizationPath);
                }
            } catch (Exception ex)
            {
                Log.Warn($"Failed to load localization file {localizationPath}. {ex.Message}");
            }

            try
            {
                if (Configuration == null)
                {
                    Configuration = new EmpyrionConfiguration(exampleConfigPath);
                    Log.Info("Loaded default configuration file.");
                    try
                    {
                        Configuration.Load(customConfigPath);
                        Log.Info("Loaded custom configuration file.");
                    }
                    catch { Log.Info("Did not load custom configuration file."); }
                }
            } catch (Exception ex)
            {
                Log.Warn($"Failed to load configuration files from {contentPath}. {ex.Message}");
            }

            Log.Info("Dark City server extension initialization done.");
        }
Esempio n. 20
0
        public override void Initialize(IModApi modAPI, ModGameAPI legacyAPI)
        {
            Logger.logLevel = LogLevel.Debug;

            this.Update_Received += ExampleMod_Update_Received;
            modAPI.Application.ChatMessageSent += ExampleMod_Event_HandleLottoChatMessage;

            Broker.Event_ConsoleCommand += Broker_Event_ConsoleCommand;

            modAPI.GameEvent        += ModAPI_GameEvent;
            Broker.Event_Statistics += PlayerDied_Event_Statistics;

            this.ChatCommands.Add(new ChatCommand(@"!repeat (?<repeat>\S+)", ChatCommand_TestMessage));
            this.ChatCommands.Add(new ChatCommand(@"!loudly (?<yellthis>.+)", (data, args) => {
                var msg = new MessageData()
                {
                    Channel    = MsgChannel.Global,
                    Text       = $"{args["yellthis"].ToUpper()}!!!!!",
                    SenderType = SenderType.System
                };
                this.GameAPI.Application.SendChatMessage(msg);
            }));

            this.ChatCommands.Add(new ChatCommand(@"!explosion", async(data, __) => {
                var dialogData = new DialogBoxData()
                {
                    Id            = data.SenderEntityId,
                    MsgText       = "BOOM!",
                    PosButtonText = "yes",
                    NegButtonText = "No"
                };
                var result = await Broker.Request_ShowDialog_SinglePlayer(dialogData);

                var resultInterpreted = result.Value == 0 ? "YES": "NO";
                MessagePlayer(data.SenderEntityId, resultInterpreted);
            }, "blows it up", PermissionType.Moderator));

            var t = new System.Timers.Timer(15000);

            t.Elapsed += T_Elapsed;
            Debugger.Break();

            t.Start();

            this.ChatCommands.Add(new ChatCommand(@"!help", async(data, __) =>
            {
                var info = await Broker.Request_Player_Info(data.SenderEntityId.ToId());

                var playerPermissionLevel = (PermissionType)info.permission;
                var header = $"Commands available to {info.playerName}; permission level {playerPermissionLevel}\n";

                var lines = this.GetChatCommandsForPermissionLevel(playerPermissionLevel)
                            .Select(x => x.ToString())
                            .OrderBy(x => x.Length).ToList();

                lines.Insert(0, header);

                var dialogData = new DialogBoxData()
                {
                    Id      = data.SenderEntityId,
                    MsgText = String.Join("\n", lines.ToArray())
                };

                Broker.Request_ShowDialog_SinglePlayer(dialogData);
            }));

            Logger.log("example mod init complete");
        }