private void PickMemoryCandidates(FFXIVRepository repository) { memoryCandidates = new List <EnmityMemory>() { new EnmityMemory55(container) }; }
public EnmityEventSource(ILogger logger) : base(logger) { // this.memory = new EnmityMemory(logger); if (FFXIVRepository.GetLanguage() == FFXIV_ACT_Plugin.Common.Language.Chinese) { memoryCandidates = new List <EnmityMemory>() { new EnmityMemory50(logger) }; } else if (FFXIVRepository.GetLanguage() == FFXIV_ACT_Plugin.Common.Language.Korean) { memoryCandidates = new List <EnmityMemory>() { new EnmityMemory50(logger) }; } else { memoryCandidates = new List <EnmityMemory>() { new EnmityMemory52(logger), new EnmityMemory50(logger) }; } RegisterEventTypes(new List <string> { EnmityTargetDataEvent, EnmityAggroListEvent, }); }
private void DispatchPartyChangeEvent() { var combatants = FFXIVRepository.GetCombatants(); if (combatants == null) { return; } List <PartyMember> result = new List <PartyMember>(24); // The partyList contents from the PartyListChangedDelegate // are equivalent to the set of ids enumerated by |query| var query = combatants.Where(c => c.PartyType != PartyTypeEnum.None); foreach (var c in query) { result.Add(new PartyMember() { id = $"{c.ID:X}", name = c.Name, worldId = c.WorldID, job = c.Job, inParty = c.PartyType == PartyTypeEnum.Party, }); } DispatchAndCacheEvent(JObject.FromObject(new { type = PartyChangedEvent, party = result, })); }
public UnstableNewLogLines(TinyIoCContainer container) { repo = container.Resolve <FFXIVRepository>(); parser = container.Resolve <NetworkParser>(); enmitySource = container.Resolve <EnmityEventSource>(); logger = container.Resolve <ILogger>(); logPath = Path.GetDirectoryName(ActGlobals.oFormActMain.LogFilePath) + "_OverlayPlugin.log"; var config = container.Resolve <BuiltinEventConfig>(); config.LogLinesChanged += (o, e) => { if (config.LogLines) { Enable(); } else { Disable(); } }; if (config.LogLines) { Enable(); } }
public FFXIVMemory(TinyIoCContainer container) { logger = container.Resolve <ILogger>(); repository = container.Resolve <FFXIVRepository>(); repository.RegisterProcessChangedHandler(UpdateProcess); }
public FFXIVProcess(TinyIoCContainer container) { logger_ = container.Resolve <ILogger>(); ffxiv_ = container.Resolve <FFXIVRepository>(); ffxiv_.RegisterProcessChangedHandler((process) => { processChanged_ = true; }); }
private void FinishLoading(object sender, BrowserLoadEventArgs e) { if (Config.ActwsCompatibility) { var charName = JsonConvert.SerializeObject(FFXIVRepository.GetPlayerName() ?? "YOU"); var charID = JsonConvert.SerializeObject(FFXIVRepository.GetPlayerID()); ExecuteScript("__OverlayPlugin_ws_faker({ type: 'broadcast', msgtype: 'SendCharName', msg: { charName: " + charName + ", charID: " + charID + " }});"); } }
public MiniParseOverlay(MiniParseOverlayConfig config, string name, TinyIoCContainer container) : base(config, name, container) { if (Overlay == null) return; repository = container.Resolve<FFXIVRepository>(); Config.ActwsCompatibilityChanged += (o, e) => { if (lastLoadedUrl != null && lastLoadedUrl != "about:blank") Navigate(config.Url); }; Config.NoFocusChanged += (o, e) => { Overlay.SetAcceptFocus(!Config.NoFocus); }; Config.ZoomChanged += (o, e) => { Overlay.Renderer.SetZoomLevel(Config.Zoom / 100.0); }; Config.ForceWhiteBackgroundChanged += (o, e) => { var color = Config.ForceWhiteBackground ? "white" : "transparent"; ExecuteScript($"document.body.style.backgroundColor = \"{color}\";"); }; Config.DisabledChanged += (o, e) => { if (Config.Disabled) { Overlay.Renderer.EndRender(); Overlay.ClearFrame(); } else { Overlay.Renderer.BeginRender(); } }; Config.VisibleChanged += (o, e) => { if (Config.MuteWhenHidden) { Overlay.Renderer.SetMuted(!Config.IsVisible); } }; Config.MuteWhenHiddenChanged += (o, e) => { Overlay.Renderer.SetMuted(Config.MuteWhenHidden ? !Config.IsVisible : false); }; if (Config.MuteWhenHidden && !Config.IsVisible) { Overlay.Renderer.SetMuted(true); } Overlay.Renderer.BrowserStartLoading += PrepareWebsite; Overlay.Renderer.BrowserLoad += FinishLoading; Overlay.Renderer.BrowserConsoleLog += Renderer_BrowserConsoleLog; }
private void PickMemoryCandidates(FFXIVRepository repository) { if (repository.GetLanguage() == FFXIV_ACT_Plugin.Common.Language.Chinese || repository.GetLanguage() == FFXIV_ACT_Plugin.Common.Language.Korean) { memoryCandidates = new List <EnmityMemory>() { new EnmityMemory52(container) }; } else { memoryCandidates = new List <EnmityMemory>() { new EnmityMemory53(container) }; } }
public MiniParseEventSource(ILogger logger) : base(logger) { this.Name = "MiniParse"; // FileChanged isn't actually raised by this event source. That event is generated in MiniParseOverlay directly. RegisterEventTypes(new List <string> { CombatDataEvent, FileChangedEvent, LogLineEvent, ImportedLogLinesEvent, }); // These events need to deliver cached values to new subscribers. RegisterCachedEventTypes(new List <string> { ChangePrimaryPlayerEvent, ChangeZoneEvent, OnlineStatusChangedEvent, PartyChangedEvent, }); RegisterEventHandler("getLanguage", (msg) => { var lang = FFXIVRepository.GetLanguage(); return(JObject.FromObject(new { language = lang.ToString("g"), languageId = lang.ToString("d"), })); }); ActGlobals.oFormActMain.BeforeLogLineRead += LogLineHandler; NetworkParser.OnOnlineStatusChanged += (o, e) => { var obj = new JObject(); obj["type"] = OnlineStatusChangedEvent; obj["target"] = e.Target; obj["rawStatus"] = e.Status; obj["status"] = StatusMap.ContainsKey(e.Status) ? StatusMap[e.Status] : "Unknown"; DispatchAndCacheEvent(obj); }; FFXIVRepository.RegisterPartyChangeDelegate((partyList, partySize) => DispatchPartyChangeEvent()); InitializeEnmityEventSource(); }
private Process FindProcess() { Process process = FFXIVRepository.GetCurrentFFXIVProcess(); if (process == null) { return(null); } if (process.ProcessName == "ffxiv") { logger.Log(LogLevel.Error, "{0}", "DX9 is not supported."); return(null); } else if (process.ProcessName != "ffxiv_dx11") { logger.Log(LogLevel.Error, "{0}", "Unknown ffxiv process."); return(null); } return(process); }
private void FinishLoading(object sender, BrowserLoadEventArgs e) { if (Config.ActwsCompatibility) { var charName = JsonConvert.SerializeObject(FFXIVRepository.GetPlayerName() ?? "YOU"); var charID = JsonConvert.SerializeObject(FFXIVRepository.GetPlayerID()); ExecuteScript(@"var msg = { charName: " + charName + ", charID: " + charID + @" }; if (window.__OverlayPlugin_ws_faker) { __OverlayPlugin_ws_faker({ type: 'broadcast', msgtype: 'SendCharName', msg }); } else { window.__OverlayPlugin_char_msg = msg; }"); } if (Preview) { try { #if DEBUG var previewPath = Path.Combine(PluginMain.PluginDirectory, "libs", "resources", "preview.json"); #else var previewPath = Path.Combine(PluginMain.PluginDirectory, "resources", "preview.json"); #endif var eventData = JObject.Parse(File.ReadAllText(previewPath)); // Since we can't be sure when the overlay is ready to receive events, we'll just send one // per second (which is the same rate the real events are sent at). previewTimer = new System.Threading.Timer((state) => { HandleEvent(eventData); ExecuteScript("document.dispatchEvent(new CustomEvent('onExampleShowcase', null));"); }, null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); } catch (Exception ex) { Registry.Resolve <ILogger>().Log(LogLevel.Error, $"{Name}: Failed to load preview data: {ex}"); } } }
public UnstableNewLogLines(TinyIoCContainer container) { repo = container.Resolve <FFXIVRepository>(); parser = container.Resolve <NetworkParser>(); var config = container.Resolve <BuiltinEventConfig>(); config.CutsceneDetectionLogChanged += (o, e) => { if (config.CutsceneDetectionLog) { Enable(); } else { Disable(); } }; if (config.CutsceneDetectionLog) { Enable(); } }
private void FindProcess() { if (processHandle != IntPtr.Zero) { if (process != null && !process.HasExited) { // The current handle is still valid. return; } else { CloseProcessHandle(); } } Process proc = FFXIVRepository.GetCurrentFFXIVProcess(); if (proc == null || proc.HasExited) { return; } if (proc.ProcessName == "ffxiv") { logger.Log(LogLevel.Error, "{0}", "DX9 is not supported."); return; } else if (proc.ProcessName != "ffxiv_dx11") { logger.Log(LogLevel.Error, "{0}", "Unknown ffxiv process."); return; } process = proc; processHandle = NativeMethods.OpenProcess(ProcessAccessFlags.VirtualMemoryRead, false, proc.Id); }
private List <Dictionary <string, object> > GetCombatants(List <uint> ids, List <string> names, List <string> props) { List <Dictionary <string, object> > filteredCombatants = new List <Dictionary <string, object> >(); var combatants = FFXIVRepository.GetCombatants(); foreach (var combatant in combatants) { if (combatant.ID == 0) { continue; } bool include = false; var combatantName = CachedCombatantPropertyInfos["Name"].GetValue(combatant); if (ids.Count == 0 && names.Count == 0) { include = true; } else { foreach (var id in ids) { if (combatant.ID == id) { include = true; break; } } if (!include) { foreach (var name in names) { if (combatantName.Equals(name)) { include = true; break; } } } } if (include) { Dictionary <string, object> filteredCombatant = new Dictionary <string, object>(); if (props.Count > 0) { foreach (var prop in props) { if (CachedCombatantPropertyInfos.ContainsKey(prop)) { filteredCombatant.Add(prop, CachedCombatantPropertyInfos[prop].GetValue(combatant)); } } } else { foreach (var prop in CachedCombatantPropertyInfos.Keys) { filteredCombatant.Add(prop, CachedCombatantPropertyInfos[prop].GetValue(combatant)); } } filteredCombatants.Add(filteredCombatant); } } return(filteredCombatants); }
public MiniParseEventSource(ILogger logger) : base(logger) { this.Name = "MiniParse"; // FileChanged isn't actually raised by this event source. That event is generated in MiniParseOverlay directly. RegisterEventTypes(new List <string> { CombatDataEvent, FileChangedEvent, LogLineEvent, ImportedLogLinesEvent, }); // These events need to deliver cached values to new subscribers. RegisterCachedEventTypes(new List <string> { ChangePrimaryPlayerEvent, ChangeZoneEvent, OnlineStatusChangedEvent, PartyChangedEvent, }); RegisterEventHandler("getLanguage", (msg) => { var lang = FFXIVRepository.GetLanguage(); return(JObject.FromObject(new { language = lang.ToString("g"), languageId = lang.ToString("d"), })); }); RegisterEventHandler("getCombatants", (msg) => { List <uint> ids = new List <uint>(); if (msg["ids"] != null) { foreach (var id in ((JArray)msg["ids"])) { ids.Add(id.ToObject <uint>()); } } List <string> names = new List <string>(); if (msg["names"] != null) { foreach (var name in ((JArray)msg["names"])) { names.Add(name.ToString()); } } List <string> props = new List <string>(); if (msg["props"] != null) { foreach (var prop in ((JArray)msg["props"])) { props.Add(prop.ToString()); } } var combatants = GetCombatants(ids, names, props); return(JObject.FromObject(new { combatants })); }); RegisterEventHandler("saveData", (msg) => { var key = msg["key"].ToString(); if (key == null) { return(null); } Config.OverlayData[key] = msg["data"]; return(null); }); RegisterEventHandler("loadData", (msg) => { var key = msg["key"].ToString(); if (key == null) { return(null); } if (!Config.OverlayData.ContainsKey(key)) { return(null); } var ret = new JObject(); ret["key"] = key; ret["data"] = Config.OverlayData[key]; return(ret); }); foreach (var propName in DefaultCombatantFields) { CachedCombatantPropertyInfos.Add(propName, typeof(FFXIV_ACT_Plugin.Common.Models.Combatant).GetProperty(propName)); } ActGlobals.oFormActMain.BeforeLogLineRead += LogLineHandler; NetworkParser.OnOnlineStatusChanged += (o, e) => { var obj = new JObject(); obj["type"] = OnlineStatusChangedEvent; obj["target"] = e.Target; obj["rawStatus"] = e.Status; obj["status"] = StatusMap.ContainsKey(e.Status) ? StatusMap[e.Status] : "Unknown"; DispatchAndCacheEvent(obj); }; FFXIVRepository.RegisterPartyChangeDelegate((partyList, partySize) => DispatchPartyChangeEvent()); }
public MiniParseOverlay(MiniParseOverlayConfig config, string name, TinyIoCContainer container) : base(config, name, container) { if (Overlay == null) { return; } repository = container.Resolve <FFXIVRepository>(); if (Config.Zoom == 1) { // Set zoom to 0% if it's set to exactly 1% since that was mistakenly the default for too long. Config.Zoom = 0; } Config.ActwsCompatibilityChanged += (o, e) => { if (lastLoadedUrl != null && lastLoadedUrl != "about:blank") { Navigate(lastLoadedUrl); } }; Config.NoFocusChanged += (o, e) => { Overlay.SetAcceptFocus(!Config.NoFocus); }; Config.ZoomChanged += (o, e) => { Overlay.Renderer.SetZoomLevel(Config.Zoom / 100.0); }; Config.ForceWhiteBackgroundChanged += (o, e) => { var color = Config.ForceWhiteBackground ? "white" : "transparent"; ExecuteScript($"document.body.style.backgroundColor = \"{color}\";"); }; Config.DisabledChanged += (o, e) => { if (Config.Disabled) { Overlay.Renderer.EndRender(); Overlay.ClearFrame(); } else { Overlay.Renderer.BeginRender(); } }; Config.VisibleChanged += (o, e) => { if (Config.MuteWhenHidden) { Overlay.Renderer.SetMuted(!Config.IsVisible); } }; Config.MuteWhenHiddenChanged += (o, e) => { Overlay.Renderer.SetMuted(Config.MuteWhenHidden ? !Config.IsVisible : false); }; Config.HideOutOfCombatChanged += (o, e) => { container.Resolve <OverlayHider>().UpdateOverlays(); }; if (Config.MuteWhenHidden && !Config.IsVisible) { Overlay.Renderer.SetMuted(true); } if (Config.HideOutOfCombat) { // Assume that we're not in combat when ACT starts. Overlay.Visible = false; } Overlay.Renderer.BrowserStartLoading += PrepareWebsite; Overlay.Renderer.BrowserLoad += FinishLoading; Overlay.Renderer.BrowserConsoleLog += Renderer_BrowserConsoleLog; }
public MiniParseEventSource(TinyIoCContainer container) : base(container) { this.Name = "MiniParse"; this.repository = container.Resolve <FFXIVRepository>(); // FileChanged isn't actually raised by this event source. That event is generated in MiniParseOverlay directly. RegisterEventTypes(new List <string> { CombatDataEvent, FileChangedEvent, LogLineEvent, ImportedLogLinesEvent, BroadcastMessageEvent, }); // These events need to deliver cached values to new subscribers. RegisterCachedEventTypes(new List <string> { ChangePrimaryPlayerEvent, ChangeZoneEvent, OnlineStatusChangedEvent, PartyChangedEvent, }); RegisterEventHandler("getLanguage", (msg) => { var lang = repository.GetLanguage(); return(JObject.FromObject(new { language = lang.ToString("g"), languageId = lang.ToString("d"), })); }); RegisterEventHandler("getCombatants", (msg) => { List <uint> ids = new List <uint>(); if (msg["ids"] != null) { foreach (var id in ((JArray)msg["ids"])) { ids.Add(id.ToObject <uint>()); } } List <string> names = new List <string>(); if (msg["names"] != null) { foreach (var name in ((JArray)msg["names"])) { names.Add(name.ToString()); } } List <string> props = new List <string>(); if (msg["props"] != null) { foreach (var prop in ((JArray)msg["props"])) { props.Add(prop.ToString()); } } var combatants = GetCombatants(ids, names, props); return(JObject.FromObject(new { combatants })); }); RegisterEventHandler("saveData", (msg) => { var key = msg["key"]?.ToString(); if (key == null) { return(null); } Config.OverlayData[key] = msg["data"]; return(null); }); RegisterEventHandler("loadData", (msg) => { var key = msg["key"]?.ToString(); if (key == null) { return(null); } if (!Config.OverlayData.ContainsKey(key)) { return(null); } var ret = new JObject(); ret["key"] = key; ret["data"] = Config.OverlayData[key]; return(ret); }); RegisterEventHandler("say", (msg) => { var text = msg["text"]?.ToString(); if (text == null) { return(null); } ActGlobals.oFormActMain.TTS(text); return(null); }); RegisterEventHandler("broadcast", (msg) => { if (!msg.ContainsKey("msg") || !msg.ContainsKey("source")) { Log(LogLevel.Error, "Called broadcast handler without specifying a source or message (\"source\" or \"msg\" property are missing)."); return(null); } if (msg["source"].Type != JTokenType.String) { Log(LogLevel.Error, "The source passed to the broadcast handler must be a string!"); return(null); } DispatchEvent(JObject.FromObject(new { type = BroadcastMessageEvent, source = msg["source"], msg = msg["msg"], })); return(null); }); try { InitFFXIVIntegration(); } catch (FileNotFoundException) { // The FFXIV plugin hasn't been loaded. } ActGlobals.oFormActMain.BeforeLogLineRead += LogLineHandler; container.Resolve <NetworkParser>().OnOnlineStatusChanged += (o, e) => { var obj = new JObject(); obj["type"] = OnlineStatusChangedEvent; obj["target"] = e.Target; obj["rawStatus"] = e.Status; obj["status"] = StatusMap.ContainsKey(e.Status) ? StatusMap[e.Status] : "Unknown"; DispatchAndCacheEvent(obj); }; }