private static void CreateSceneObject() { if (GameObject.Find(SceneObjectName) != null) { Logger.Error("Another version of the library is already loaded. The HugsLib assembly should be loaded as a standalone mod."); return; } var obj = new GameObject(SceneObjectName); GameObject.DontDestroyOnLoad(obj); obj.AddComponent <UnityProxyComponent>(); }
private static void CreateSceneObject() { // this must execute in the main thread LongEventHandler.ExecuteWhenFinished(() => { if (GameObject.Find(SceneObjectName) != null) { Logger.Error("Another version of the library is already loaded. The HugsLib assembly should be loaded as a standalone mod."); return; } var obj = new GameObject(SceneObjectName); GameObject.DontDestroyOnLoad(obj); obj.AddComponent <UnityProxyComponent>(); }); }
protected override void InitializeMonitor() { ModLogger.Debug("Initializing prop monitor"); try { // Clear any existing data from the overwatch container OverwatchPropContainer.Instance.ClearCache(); // Process the list of existing props when initializing to make sure the list is up-to-date var capacity = Singleton <PropManager> .instance.m_props.m_buffer.Count(); Enumerable.Range(0, capacity).DoAll(i => ProcessProp((ushort)i)); // Store a reference to the current frame index so we know from which frame we need to process on the next update cycle MarkFrame(); // Mark the monitor as initialized and spinning MarkInitialized(); OverwatchControl.Instance.PropMonitorSpun = true; ModLogger.Debug("Prop monitor initialized"); } catch (Exception ex) { ModLogger.Error("An error occured while initializing the prop monitor"); ModLogger.Exception(ex); MarkTerminated(); } }
public override void Start() { base.Start(); if (Parent == null) { ModLogger.Error(String.Format("Parent not set in {0}", this.GetType().Name)); return; } width = Parent.width; relativePosition = Vector3.zero; isVisible = true; canFocus = true; isInteractive = true; _drag.width = width - UIConstants.DragHandleWidthOffset; _drag.height = height; _drag.relativePosition = Vector3.zero; _drag.target = Parent; _icon.spriteName = IconSprite; _icon.relativePosition = UIConstants.TitleIconRelativePosition; _title.relativePosition = UIConstants.TitleRelativePosition; _title.text = TitleText; _close.relativePosition = new Vector3(width - UIConstants.CloseButtonRelativePositionOffset, 2); _close.normalBgSprite = UIConstants.CloseButtonNormalBgSprite; _close.hoveredBgSprite = UIConstants.CloseButtonHoveredBgSprite; _close.pressedBgSprite = UIConstants.CloseButtonPressedBgSprite; _close.eventClick += (component, param) => Parent.Hide(); }
public override void OnLevelUnloading() { // Don't unload in asset and map editor if (_mode != LoadMode.LoadGame && _mode != LoadMode.NewGame) { return; } try { ModLogger.Debug("Destroying main window"); // Destroy the mainwindow when unloading to make sure a fresh new window is used for the next game if (_mainWindow != null) { GameObject.Destroy(_mainWindow.gameObject); } ModLogger.Debug("Main window destroyed"); } catch (Exception ex) { ModLogger.Error("An error occured while destroying the main window"); ModLogger.Exception(ex); } }
public sealed override void OnLevelLoaded(LoadMode mode) { _mode = mode; // Don't load in asset and map editor if (mode != LoadMode.LoadGame && mode != LoadMode.NewGame) { return; } try { ModLogger.Debug("Creating main window"); // Get a handle to the main game view UIView aView = UIView.GetAView(); // Create the gameobject and attach a mainwindow instance GameObject goMainWindow = new GameObject(WorkshopMonitorMainWindowGameObjectName); _mainWindow = goMainWindow.AddComponent <UIMainWindow>(); _mainWindow.transform.parent = aView.transform; ModLogger.Debug("Main window created"); } catch (Exception ex) { ModLogger.Error("An error occured while creating the main window"); ModLogger.Exception(ex); } }
public void Error(string error) { if (_logger is ModLogger) { _logger.Error(error); } }
private void RunUpdateCycle() { try { // Get a reference to the current frame int end = GetFrame(); // Process all frames between the previous frame marker and the current frame while (_lastProcessedFrame != end) { _lastProcessedFrame = GetFrame(_lastProcessedFrame + 1); int[] boundaries = GetFrameBoundaries(_lastProcessedFrame); for (int i = boundaries[0]; i <= boundaries[1]; i++) { CheckAssetExistence((ushort)i); } } } catch (Exception ex) { ModLogger.Error("An unexpected error occured while running an update cycle in the building monitor"); ModLogger.Exception(ex); MarkTerminated(); } }
public override void OnBeforeSimulationTick() { // Exit if the monitor was terminated because of an error occured when updating overwatch data if (Terminated) { return; } // Exit if the prop monitor has not been loaded yet by the overwatch loader (prevents issues when the loader is not started yet but the monitor is) if (!OverwatchControl.Instance.PropMonitorSpun) { MarkUninitialized(); return; } // Exit if the prop monitor has not been initialized yet (initialization happens in OnUpdate) if (!Initialized) { return; } // Exit if no prop changes occured since the previous tick if (!Singleton <PropManager> .instance.m_propsUpdated) { return; } try { for (int i = 0; i < Singleton <PropManager> .instance.m_updatedProps.Length; i++) { ulong updatedPropId = Singleton <PropManager> .instance.m_updatedProps[i]; if (updatedPropId != 0) { for (int j = 0; j < 64; j++) { if ((updatedPropId & (ulong)1 << j) != 0) { ushort id = (ushort)(i << 6 | j); ProcessProp(id); } } } } } catch (Exception ex) { ModLogger.Error("An error occured while updating prop information"); ModLogger.Exception(ex); MarkTerminated(); } base.OnBeforeSimulationTick(); }
public void Update() { try { int workshopAssetCount = _workshopAssets.Count(); ModLogger.Debug("WorkshopAssetMonitor is updating {0} workshop assets", workshopAssetCount); foreach (var item in _workshopAssets) { item.UpdateInstanceCount(); } ModLogger.Debug("WorkshopMonitor updated {0} workshop assets", workshopAssetCount); } catch (Exception ex) { ModLogger.Error("An error occured while updating the workshop item list, the numbers displayed could be incorrect"); ModLogger.Exception(ex); } }
protected ModBase() { modContentPackInt = CurrentlyProcessedContentPack; Logger = new ModLogger(LogIdentifierSafe); var settingsPackId = SettingsIdentifier; if (!string.IsNullOrEmpty(settingsPackId)) { if (PersistentDataManager.IsValidElementName(settingsPackId)) { Settings = HugsLibController.Instance.Settings.GetModSettings(settingsPackId, modContentPackInt?.Name); } else { Logger.Error($"string \"{settingsPackId}\" cannot be used as a settings identifier. " + $"Override {nameof(ModBase)}.{nameof(SettingsIdentifier)} to manually specify one. " + $"See {nameof(SettingsIdentifier)} autocomplete documentation for expected format."); } } }
public override void OnLevelUnloading() { // Don't stop in asset and map editor if (_mode != LoadMode.LoadGame && _mode != LoadMode.NewGame) { return; } try { ModLogger.Debug("Stopping WorkshopAssetMonitor"); WorkshopAssetMonitor.Instance.Stop(); ModLogger.Debug("WorkshopAssetMonitor stopped"); } catch (Exception ex) { ModLogger.Error("An error occured while stopping the WorkshopAssetMonitor"); ModLogger.Exception(ex); } }
public override void OnUpdate(float realTimeDelta, float simulationTimeDelta) { // Exit if the monitor was terminated because of an error occured when updating overwatch data if (_terminated) { return; } // Exit if the monitor has not been loaded yet by the overwatch loader when a game is loaded (prevents issues when the loader is not started yet but the monitor is) if (!OverwatchControl.Instance.GameLoaded) { return; } try { // Initialize the monitor if it wasn't initialized yet if (!_initialized) { InitializeMonitor(); } // Run an update cycle if the simulation is not currently paused else if (!SimulationManager.instance.SimulationPaused) { RunUpdateCycle(); } } catch (Exception ex) { ModLogger.Error(string.Format("An unexpected error occured while updating the {0}", _monitorType)); ModLogger.Exception(ex); _terminated = true; } base.OnUpdate(realTimeDelta, simulationTimeDelta); }
public bool Load() { if (mStarted) { if (mErrorOnLoading) { return(false); } return(true); } mErrorOnLoading = false; Logger.Log($"Version '{Info.Version}'. Loading."); if (string.IsNullOrEmpty(Info.AssemblyName)) { mErrorOnLoading = true; Logger.Error(string.Format("{0} is null.", "AssemblyName")); } if (string.IsNullOrEmpty(Info.EntryMethod)) { mErrorOnLoading = true; Logger.Error(string.Format("{0} is null.", "EntryMethod")); } if (!string.IsNullOrEmpty(Info.ManagerVersion) && ManagerVersion > GetVersion()) { mErrorOnLoading = true; Logger.Error($"Mod Manager must be version '{Info.ManagerVersion}' or higher."); } if (Requirements.Count > 0) { foreach (KeyValuePair <string, Version> requirement in Requirements) { string key = requirement.Key; ModEntry modEntry = FindMod(key); if (modEntry == null || modEntry.Assembly == null) { mErrorOnLoading = true; Logger.Error($"Required mod '{key}' not loaded."); } else if (!modEntry.Enabled) { mErrorOnLoading = true; Logger.Error($"Required mod '{key}' disabled."); } else if (!modEntry.Active) { Logger.Log($"Required mod '{key}' inactive."); } else if (requirement.Value != null && requirement.Value > modEntry.Version) { mErrorOnLoading = true; Logger.Error($"Required mod '{key}' must be version '{requirement.Value}' or higher."); } } } if (mErrorOnLoading) { return(false); } string text = System.IO.Path.Combine(Path, Info.AssemblyName); if (File.Exists(text)) { try { if (mAssembly == null) { mAssembly = Assembly.LoadFile(text); } } catch (Exception ex) { mErrorOnLoading = true; Logger.Error($"Error loading file '{text}'."); Logger.Error(ex.ToString()); return(false); } try { object[] param = new object[1] { this }; Type[] types = new Type[1] { typeof(ModEntry) }; if (FindMethod(Info.EntryMethod, types, showLog: false) == null) { param = null; types = null; } if (!Invoke(Info.EntryMethod, out object result, param, types) || (result != null && !(bool)result)) { mErrorOnLoading = true; Logger.Log("Not loaded."); } } catch (Exception ex2) { mErrorOnLoading = true; Logger.Error($"Error loading file '{text}'."); Logger.Error(ex2.ToString()); return(false); } mStarted = true; if (!mErrorOnLoading && Enabled) { Active = true; return(true); } } else { mErrorOnLoading = true; Logger.Error($"'{text}' not found."); } return(false); }
public void Start() { try { ModLogger.Debug("WorkshopAssetMonitor is loading workshop assets"); // The package manager monitors the list of workshop assets, so retrieve the packageid from each item var workshopIds = PackageManager .FilterAssets(UserAssetType.CustomAssetMetaData) .Where(a => a.isWorkshopAsset) .Select(a => new { Asset = a, Metadata = a.Instantiate <CustomAssetMetaData>() }) .Select(a => ulong.Parse(a.Asset.package.packageName)) .Distinct(); // The PrefabCollections monitor the list of all prefabs available in the game, which includes the default CS prefabs and the custom prefabs from workshop assets // Try to match the prefabs with the workshop packageid list to make sure only workshopassets are loaded. for (int i = 0; i < PrefabCollection <PropInfo> .PrefabCount(); i++) { PropInfo propPrefab = PrefabCollection <PropInfo> .GetPrefab((uint)i); if (propPrefab != null) { var workshopPropMatch = Regex.Match(propPrefab.name, RegexExpression.BuildingName, RegexOptions.IgnoreCase); if (workshopPropMatch.Success) { var workshopPropId = ulong.Parse(workshopPropMatch.Groups["packageid"].Value); if (workshopIds.Any(id => id == workshopPropId)) { _workshopAssets.Add(new WorkshopProp(workshopPropId, workshopPropMatch.Groups["prefabname"].Value, propPrefab.name)); } } } } for (int i = 0; i < PrefabCollection <TreeInfo> .PrefabCount(); i++) { TreeInfo treePrefab = PrefabCollection <TreeInfo> .GetPrefab((uint)i); if (treePrefab != null) { var workshopTreeMatch = Regex.Match(treePrefab.name, RegexExpression.BuildingName, RegexOptions.IgnoreCase); if (workshopTreeMatch.Success) { var workshopPropId = ulong.Parse(workshopTreeMatch.Groups["packageid"].Value); if (workshopIds.Any(id => id == workshopPropId)) { _workshopAssets.Add(new WorkshopTree(workshopPropId, workshopTreeMatch.Groups["prefabname"].Value, treePrefab.name)); } } } } for (int i = 0; i < PrefabCollection <BuildingInfo> .PrefabCount(); i++) { BuildingInfo buildingPrefab = PrefabCollection <BuildingInfo> .GetPrefab((uint)i); if (buildingPrefab != null) { var workshopBuildingMatch = Regex.Match(buildingPrefab.name, RegexExpression.BuildingName, RegexOptions.IgnoreCase); if (workshopBuildingMatch.Success) { var workshopBuildingId = ulong.Parse(workshopBuildingMatch.Groups["packageid"].Value); if (workshopIds.Any(id => id == workshopBuildingId)) { _workshopAssets.Add(new WorkshopBuilding(workshopBuildingId, workshopBuildingMatch.Groups["prefabname"].Value, buildingPrefab.name, buildingPrefab.GetService().ToAssetType())); } } } } ModLogger.Debug("WorkshopAssetMonitor loaded {0} workshop assets", GetWorkshopAssetCount()); } catch (Exception ex) { ModLogger.Error("An error occured while starting the workshop monitor, no workshop assets where loaded"); ModLogger.Exception(ex); } }