DutyContent/DcControl.cs
2023-02-16 19:33:37 +09:00

451 lines
11 KiB
C#

using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Windows.Forms;
using Advanced_Combat_Tracker;
using DutyContent.Properties;
using DutyContent.Tab;
using DutyContent.ThirdParty;
using Timer = System.Timers.Timer;
namespace DutyContent
{
public partial class DcControl : UserControl, IActPluginV1
{
public static string PluginName => "DutyContent";
private static DcControl _self;
public static DcControl Self => _self;
//
private ActPluginData _ffxiv_plugin_data;
private bool _is_form_loaded;
private bool _is_plugin_initializing;
private TabPage _act_tab;
private Label _act_label;
private Timer _save_timer;
private Timer _update_timer;
private NativeMethods.ProcessHandle _game_process;
private long _game_connection_tick = DateTime.Now.Ticks;
private bool _game_exist;
private bool _game_active;
private string _game_zone;
private IPAddress _game_ipaddr = IPAddress.None;
//
private const int IntervalGameActive = 50;
private const int IntervalGameExist = 300;
private const int IntervalGameNone = 500;
//
public DcControl()
{
_self = this;
//
RegisterActAssemblies();
InitializeComponent();
foreach (var f in Application.OpenForms)
{
if (f == ActGlobals.oFormActMain)
{
_is_form_loaded = true;
break;
}
}
//
DutyForm dutyform = new DutyForm();
tabPageDuty.Controls.Add(dutyform.Controls[0]);
PingForm pingform = new PingForm();
tabPagePing.Controls.Add(pingform.Controls[0]);
ConfigForm configform = new ConfigForm();
tabPageConfig.Controls.Add(configform.Controls[0]);
LogForm logform = new LogForm();
tabPageLog.Controls.Add(logform.Controls[0]);
}
//
public void RegisterActAssemblies()
{
var pin = ActGlobals.oFormActMain.ActPlugins.FirstOrDefault(x => x.pluginFile.Name.Equals("DutyContent.dll"));
DcConfig.PluginPath = pin?.pluginFile.DirectoryName;
DcConfig.DataPath = Path.Combine(DcConfig.PluginPath, "Data");
DcConfig.PluginConfigPath = Path.Combine(DcConfig.PluginPath, "DutyContent.config");
var actdata = ActGlobals.oFormActMain.AppDataFolder.FullName;
DcConfig.ActConfigPath = Path.Combine(actdata, "Config", "DutyContent.config");
}
//
public void InitPlugin(TabPage tab, Label label)
{
_act_tab = tab;
_act_label = label;
if (_is_form_loaded)
ActPluginInitialize();
else
ActGlobals.oFormActMain.Shown += OFormActMain_Shown;
var actinfo = Assembly.GetAssembly(typeof(ActGlobals));
Logger.I(5, actinfo.GetName().Version);
if (_ffxiv_plugin_data == null)
{
_ffxiv_plugin_data = ActGlobals.oFormActMain.ActPlugins.Where(x =>
x.pluginFile.Name.ToUpper().StartsWith("FFXIV_ACT_PLUGIN") &&
(x.lblPluginStatus.Text.ToUpper().StartsWith("FFXIV PLUGIN STARTED.") ||
x.lblPluginStatus.Text.ToUpper().StartsWith("FFXIV_ACT_PLUGIN STARTED.")))
.Select(x => x)
.FirstOrDefault();
}
if (_ffxiv_plugin_data == null)
Logger.E(2); // FFXIV plugin is missing!
else
{
var ids = ((FFXIV_ACT_Plugin.FFXIV_ACT_Plugin)_ffxiv_plugin_data.pluginObj).DataSubscription;
ids.NetworkReceived -= FFXIVPlugin_NetworkReceived;
ids.NetworkReceived += FFXIVPlugin_NetworkReceived;
ids.ZoneChanged -= FFXIVPlugin_ZoneChanged;
ids.ZoneChanged += FFXIVPlugin_ZoneChanged;
Logger.I(6, FileVersionInfo.GetVersionInfo(_ffxiv_plugin_data.pluginFile.FullName).FileVersion);
}
// begin region check - from cacbot "VersionChecker.cs"
try
{
var mach = Assembly.Load("Machina.FFXIV");
var opcode_manager_type = mach.GetType("Machina.FFXIV.Headers.Opcodes.OpcodeManager");
var opcode_manager = opcode_manager_type.GetProperty("Instance").GetValue(null);
var machina_region = opcode_manager_type.GetProperty("GameRegion").GetValue(opcode_manager).ToString();
switch (machina_region)
{
//case "Chinese": // no chinese support now
case "Korean":
DcConfig.GameRegion = 1;
break;
default:
DcConfig.GameRegion = 0;
break;
}
Logger.I(45, machina_region, DcConfig.GameRegion);
}
catch (Exception ex)
{
Logger.Ex(ex, 44);
DcConfig.GameRegion = 0;
}
/* No below 6.2 version [2022-2-16]
if (DcConfig.GameRegion != 0)
DcConfig.Duty.PacketForLocal = true;
*/
// end region check
_save_timer = new Timer { Interval = 5000 };
_save_timer.Elapsed += (sender, e) =>
{
DcConfig.SaveConfig();
_save_timer.Enabled = false;
};
_update_timer = new Timer { Interval = IntervalGameExist };
_update_timer.Elapsed += (sender, e) =>
{
UpdateAndCheckProc();
_update_timer.Interval = _game_exist ? _game_active ?
IntervalGameActive : IntervalGameExist : IntervalGameNone;
};
_update_timer.Start();
}
//
public void DeInitPlugin()
{
_update_timer.Stop();
_save_timer.Stop();
DcConfig.PluginEnable = false;
UpdateNotifyForm.Self?.PluginDeinitialize();
PingForm.Self?.PluginDeinitialize();
DutyForm.Self?.PluginDeinitialize();
ConfigForm.Self?.PluginDeinitialize();
LogForm.Self?.PluginDeinitialize();
DcConfig.SaveConfig();
_act_tab = null;
if (_act_label != null)
{
_act_label.Text = "Closed";
_act_label = null;
}
}
private void OFormActMain_Shown(object sender, EventArgs e)
{
_is_form_loaded = true;
ActPluginInitialize();
}
//
private void ActPluginInitialize()
{
if (_is_plugin_initializing)
return;
_is_plugin_initializing = true;
_act_label.Text = "Starting...";
//
Locale.Initialize(Resources.DefaultMessage);
Logger.I(4, DcConfig.PluginVersion.ToString());
DcConfig.LoadConfig();
ShowStatusBarAsConfig(true);
DcConfig.ReadLanguage(true);
DcContent.ReadContent();
DcConfig.ReadPacket();
UpdateUiLocale();
lblStatusLeft.Text = Locale.Text(99, DcConfig.PluginVersion); // once here
//
Dock = DockStyle.Fill;
_act_tab.Controls.Add(this);
//
LogForm.Self?.PluginInitialize();
ConfigForm.Self?.PluginInitialize();
DutyForm.Self?.PluginInitialize();
PingForm.Self?.PluginInitialize();
tabMain.SelectedTab = tabPageDuty;
//
if (DcConfig.DataRemoteUpdate)
{
var tag = Updater.CheckPluginUpdate(out string body);
if (tag > DcConfig.PluginTag)
{
UpdateNotifyForm frm = new UpdateNotifyForm(tag, body);
frm.PluginInitialize();
frm.UpdateUiLocale();
TabPage tp = new TabPage(Locale.Text(206));
try
{
// why? sometimes trouble
tp.Controls.Add(frm.Controls[0]);
}
catch (Exception ex)
{
Logger.Ex(ex);
}
tabMain.TabPages.Add(tp);
if (DcConfig.LastUpdatedPlugin < tag)
{
tabMain.SelectedTab = tp;
DcConfig.LastUpdatedPlugin = tag;
DcConfig.SaveConfig();
}
Logger.C(Color.Aquamarine, 207, DcConfig.PluginTag, tag);
}
}
//
DcConfig.PluginEnable = true;
_is_plugin_initializing = false;
}
//
private void TabMain_DrawItem(object sender, DrawItemEventArgs e)
{
var g = e.Graphics;
TabPage p = tabMain.TabPages[e.Index];
Rectangle r = tabMain.GetTabRect(e.Index);
StringFormat s = new StringFormat
{
Alignment = StringAlignment.Near,
LineAlignment = StringAlignment.Center,
};
Brush b, h;
Font f;
if (tabMain.SelectedIndex == e.Index)
{
f = new Font(tabMain.Font.FontFamily, 14.0f, FontStyle.Bold, GraphicsUnit.Pixel);
#if false
b = new SolidBrush(Color.Black);
h = SystemBrushes.Window;
#else
b = new SolidBrush(Color.White);
h = SystemBrushes.Highlight;
#endif
}
//else if (p.col)
else
{
f = new Font(tabMain.Font.FontFamily, 14.0f, FontStyle.Regular, GraphicsUnit.Pixel);
b = new SolidBrush(Color.DarkSlateGray);
h = SystemBrushes.Control;
}
g.FillRectangle(h, r);
g.DrawString(p.Text, f, b, r, new StringFormat(s));
}
//
public void RefreshSaveConfig(int interval = 5000)
{
_save_timer.Enabled = false;
_save_timer.Interval = interval;
_save_timer.Start();
}
//
private void UpdateAndCheckProc()
{
if (_game_process == null || _game_process.Process.HasExited)
{
_game_exist = false;
_game_active = false;
// will be update game status next time
var p = (from x in Process.GetProcessesByName("ffxiv_dx11") where !x.HasExited && x.MainModule != null && x.MainModule.ModuleName == "ffxiv_dx11.exe" select x).FirstOrDefault();
if (p != null && p.HasExited)
p = null;
if (((_game_process == null) != (p == null)) ||
(_game_process != null && p != null && _game_process.Process.Id != p.Id))
{
_game_process = p != null ? new NativeMethods.ProcessHandle(p) : null;
}
}
else
{
_game_exist = true;
//
var fgw = NativeMethods.GetForegroundWindow();
NativeMethods.GetWindowThreadProcessId(fgw, out int id);
_game_active = _game_process.Process.Id == id;
//
var now = DateTime.Now.Ticks;
var delta = now - _game_connection_tick;
var span = new TimeSpan(delta);
if (span.TotalSeconds > 2)
{
_game_connection_tick = now;
DcConfig.Connections.BuildConnections(_game_process.Process, out var retaddr);
if (!_game_ipaddr.Equals(retaddr))
{
if (!retaddr.Equals(IPAddress.None))
Logger.I(42, retaddr);
else
Logger.I(42, Locale.Text(43));
_game_ipaddr = retaddr;
DutyForm.Self?.ResetContentItems();
}
}
}
var zone = ActGlobals.oFormActMain.CurrentZone;
if (_game_zone == null || !zone.Equals(_game_zone))
_game_zone = zone;
}
//
private void FFXIVPlugin_NetworkReceived(string connection, long epoch, byte[] message)
{
if (message.Length < 32)
return;
DutyForm.Self?.PacketHandler(connection, message);
}
//
private void FFXIVPlugin_ZoneChanged(uint zoneId, string zoneName)
{
DutyForm.Self?.ZoneChanged(zoneId, zoneName);
lblStatusLeft.Text = Locale.Text(34, zoneName, zoneId);
}
//
public void UpdateUiLocale()
{
FontUtilities.SimpleChangeFont(this, DcConfig.UiFontFamily, true);
_act_label.Text = Locale.Text(1); // Duty ready
_act_tab.Text = Locale.Text(0); // FFXIV dc
tabPageDuty.Text = Locale.Text(300);
DutyForm.Self?.UpdateUiLocale();
tabPagePing.Text = Locale.Text(400);
PingForm.Self?.UpdateUiLocale();
tabPageConfig.Text = Locale.Text(200);
ConfigForm.Self?.UpdateUiLocale();
tabPageLog.Text = Locale.Text(500);
LogForm.Self?.UpdateUiLocale();
UpdateNotifyForm.Self?.UpdateUiLocale();
}
//
public void ShowStatusBarAsConfig(bool force = false)
{
if (DcConfig.StatusBar)
{
if (!lblStatusLeft.Visible || force)
{
tabMain.Dock = DockStyle.None;
lblStatusLeft.Visible = true;
}
}
else
{
if (lblStatusLeft.Visible || force)
{
lblStatusLeft.Visible = false;
tabMain.Dock = DockStyle.Fill;
}
}
}
}
}