DutyContent/Tab/DutyForm.cs
2021-12-14 13:43:07 +09:00

1703 lines
40 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Http;
using System.Text;
using System.IO;
namespace DutyContent.Tab
{
public partial class DutyForm : Form, Interface.ISuppLocale, Interface.IPacketHandler, Interface.ISuppActPlugin
{
private static DutyForm _self;
public static DutyForm Self => _self;
//
private bool _is_lock_fate;
private ushort _last_fate = 0;
private ushort _last_zone = 0;
//
private bool _is_packet_finder;
private DcContent.SaveTheQueenType _stq_type = DcContent.SaveTheQueenType.No;
private DcConfig.PacketConfig _new_packet;
//
private Dictionary<string, string> _packet_list = new Dictionary<string, string>();
//
private Overlay.DutyOvForm _overlay;
//
public DutyForm()
{
_self = this;
InitializeComponent();
_overlay = new Overlay.DutyOvForm();
}
private void DutyTabForm_FormClosing(object sender, FormClosingEventArgs e)
{
}
public void PluginInitialize()
{
//
lblCurrentDataSet.Text = DcContent.DisplayLanguage;
//
RefreshDatasetList();
RefreshPacketList();
//
chkEnableOverlay.Checked = DcConfig.Duty.EnableOverlay;
progbOverlayTransparent.Enabled = DcConfig.Duty.EnableOverlay;
btnOverlayDimming.Enabled = DcConfig.Duty.EnableOverlay;
chkOverlayClickThru.Checked = DcConfig.Duty.OverlayClickThru;
//
_overlay.SetText(Locale.Text(99, DcConfig.PluginVersion.ToString()));
_overlay.Location = DcConfig.Duty.OverlayLocation;
if (DcConfig.Duty.EnableOverlay)
_overlay.Show();
else
_overlay.Hide();
if (DcConfig.Duty.OverlayClickThru)
_overlay.SetClickThruStatus(true);
//
chkEnableSound.Checked = DcConfig.Duty.EnableSound;
txtSoundInstance.Text = DcConfig.Duty.SoundInstanceFile;
txtSoundInstance.Enabled = DcConfig.Duty.EnableSound;
btnSoundFindInstance.Enabled = DcConfig.Duty.EnableSound;
btnSoundPlayInstance.Enabled = DcConfig.Duty.EnableSound;
txtSoundFate.Text = DcConfig.Duty.SoundFateFile;
txtSoundFate.Enabled = DcConfig.Duty.EnableSound;
btnSoundFindFate.Enabled = DcConfig.Duty.EnableSound;
btnSoundPlayFate.Enabled = DcConfig.Duty.EnableSound;
//
chkUseNotifyLine.Checked = DcConfig.Duty.UseNotifyLine;
txtLineToken.Text = DcConfig.Duty.NotifyLineToken;
chkUseNotifyTelegram.Checked = DcConfig.Duty.UseNotifyTelegram;
txtTelegramId.Text = DcConfig.Duty.NotifyTelegramId;
txtTelegramToken.Text = DcConfig.Duty.NotifyTelegramToken;
chkUseNotifyDiscowk.Checked = DcConfig.Duty.UseNotifyDiscordWebhook;
txtDiscowkUrl.Text = DcConfig.Duty.NotifyDiscordWebhookUrl;
chkDiscowkTts.Checked = DcConfig.Duty.NotifyDiscordWebhookTts;
btnTestNotify.Enabled = DcConfig.Duty.EnableNotify;
//
switch (DcConfig.Duty.ActiveFate)
{
case 0: rdoFatePreset1.Checked = true; break;
case 1: rdoFatePreset2.Checked = true; break;
case 2: rdoFatePreset3.Checked = true; break;
case 3: rdoFatePreset4.Checked = true; break;
}
UpdateFates();
//
if (cboPacketset.SelectedIndex >= 0)
{
var p = _packet_list.ElementAt(cboPacketset.SelectedIndex);
RemotePacketUpdate(p.Key);
}
}
public void PluginDeinitialize()
{
_overlay.Hide();
_overlay = null;
}
private void SaveConfig(int interval = 5000)
{
DcControl.Self.RefreshSaveConfig(interval);
}
public void RefreshLocale()
{
}
public void UpdateUiLocale()
{
tabPageContent.Text = Locale.Text(301);
tabPageSetting.Text = Locale.Text(302);
tabPagePacket.Text = Locale.Text(337);
lblDataSet.Text = Locale.Text(304);
lblPacketSet.Text = Locale.Text(336);
btnResetContentList.Text = Locale.Text(347);
chkEnableOverlay.Text = Locale.Text(306);
lblOverlayTransparent.Text = Locale.Text(307);
chkOverlayClickThru.Text = Locale.Text(104);
chkEnableSound.Text = Locale.Text(308);
lblSoundInstance.Text = Locale.Text(309);
lblSoundFate.Text = Locale.Text(310);
chkUseNotifyLine.Text = Locale.Text(311);
lblLineToken.Text = Locale.Text(312);
chkUseNotifyTelegram.Text = Locale.Text(313);
lblTelegramId.Text = Locale.Text(314);
lblTelegramToken.Text = Locale.Text(315);
chkUseNotifyDiscowk.Text = Locale.Text(338);
chkDiscowkTts.Text = Locale.Text(341);
lblDiscowkUrl.Text = Locale.Text(339);
btnTestNotify.Text = Locale.Text(340);
lblPacketFinder.Text = Locale.Text(316);
lblPacketDesc.Text = Locale.Text(317);
lblPacketBozja.Text = Locale.Text(318);
lstPacketInfo.Columns[0].Text = Locale.Text(319);
lstPacketInfo.Columns[1].Text = Locale.Text(320);
lstPacketInfo.Columns[2].Text = Locale.Text(321);
lstPacketInfo.Columns[3].Text = Locale.Text(322);
lstBozjaInfo.Columns[0].Text = Locale.Text(323);
lstBozjaInfo.Columns[1].Text = Locale.Text(324);
lstBozjaInfo.Columns[2].Text = Locale.Text(325);
lstBozjaInfo.Columns[3].Text = Locale.Text(326);
btnPacketStart.Text = Locale.Text(10007);
btnPacketApply.Text = Locale.Text(10009);
// content reset
lstContents.InitializeContentList(
Locale.Text(343), // ID
Locale.Text(344), // Type
Locale.Text(345), // %
Locale.Text(346)); // Name
Image im_r = Properties.Resources.pix_rdrt_red;
Image im_g = Properties.Resources.pix_rdrt_green;
Image im_p = Properties.Resources.pix_rdrt_puple;
Image im_b = Properties.Resources.pix_rdrt_bline;
lstContents.ClearImages();
lstContents.AddCategoryImage(im_b, Locale.Text(27), Brushes.Black); // 0, none
lstContents.AddCategoryImage(im_g, Locale.Text(21)); // 1, roulette
lstContents.AddCategoryImage(im_g, Locale.Text(22)); // 2, instance
lstContents.AddCategoryImage(im_r, Locale.Text(23)); // 3, FATE
lstContents.AddCategoryImage(im_r, Locale.Text(24)); // 4, skirmish
lstContents.AddCategoryImage(im_p, Locale.Text(25)); // 5, CE
lstContents.AddCategoryImage(im_p, Locale.Text(38)); // 6, Match
lstContents.AddCategoryImage(im_g, Locale.Text(39)); // 7, Entry
lstContents.AddContentItem(0, Locale.Text(27));
}
public void PacketHandler(string pid, byte[] message)
{
if (_is_packet_finder)
PacketFinderHandler(message);
var opcode = BitConverter.ToUInt16(message, 18);
if (opcode != DcConfig.Packet.OpFate &&
opcode != DcConfig.Packet.OpDuty &&
opcode != DcConfig.Packet.OpMatch &&
opcode != DcConfig.Packet.OpInstance &&
opcode != DcConfig.Packet.OpZone &&
opcode != DcConfig.Packet.OpCe)
return;
var data = message.Skip(32).ToArray();
// FATE
if (opcode == DcConfig.Packet.OpFate)
{
var fcode = BitConverter.ToUInt16(data, 4);
if (fcode > 100)
{
// 53=begin, 54=end, 62=progress
if (data[0] == 53)
{
var fate = DcContent.GetFate(fcode);
TraceFate(fcode, true, fate, 0);
if (DcConfig.Duty.Fates[DcConfig.Duty.ActiveFate].Selected.Contains(fcode))
{
PlayEffectSoundFate();
NotifyFate(fate);
_overlay.PlayFate(fate);
}
_last_fate = fcode;
}
else if (data[0] == 62 && data[8] > 0) // more than 0%
{
var fate = DcContent.TryFate(fcode);
if (fate != null)
TraceFate(fcode, false, fate, data[8]);
else
{
if (DcConfig.DebugEnable)
{
WriteLog(Color.Magenta, 37, 12, fcode);
_last_fate = fcode;
}
}
}
else if (data[0] == 54)
{
var fate = DcContent.TryFate(fcode);
if (fate != null)
TraceFate(fcode, false, fate);
}
}
}
// Duty
else if (opcode == DcConfig.Packet.OpDuty)
{
var rcode = data[8];
if (rcode != 0)
{
var roulette = DcContent.GetRoulette(rcode);
TraceEntryRoulette(roulette);
_overlay.PlayQueue(roulette.Name);
}
else
{
// TODO: is this working?
var insts = new List<int>();
for (var i = 0; i < 5; i++)
{
var icode = BitConverter.ToUInt16(data, 12 + (i * 4));
if (icode == 0)
break;
}
if (insts.Any())
{
TraceEntryInstance(insts);
_overlay.PlayQueue(Locale.Text(10006, $"#{insts.Count}"));
}
}
DcContent.Missions.Clear();
}
// match
else if (opcode == DcConfig.Packet.OpMatch)
{
var rcode = BitConverter.ToUInt16(data, 2);
var icode = BitConverter.ToUInt16(data, 20);
string name;
if (icode == 0 && rcode != 0)
{
var roulette = DcContent.GetRoulette(rcode);
TraceMatchRoulette(roulette);
name = roulette.Name;
}
else if (icode != 0)
{
var instance = DcContent.GetInstance(icode);
TraceMatchInstance(instance);
name = instance.Name;
}
else
{
// ???
name = Locale.Text(10003, icode);
}
PlayEffecSoundInstance();
NotifyMatch(name);
_overlay.PlayMatch(name);
}
// instance
else if (DcConfig.Packet.OpInstance != 0 && opcode == DcConfig.Packet.OpInstance)
{
// 0[2] instance number
// 2[2] ?
// 4[1] 0=enter, 4=enter, 5=leave
if (data[4] == 0)
{
var icode = BitConverter.ToUInt16(data, 0);
var instance = DcContent.GetInstance(icode);
TraceEnterInstance(instance);
_overlay.PlayMatch(Locale.Text(10004, instance.Name));
DcContent.Missions.Clear();
ResetContentItems(); // frankly no meaning to here
}
else if (data[4] != 4)
{
_overlay.PlayNone();
}
}
// zone
else if (DcConfig.Packet.OpZone != 0 && opcode == DcConfig.Packet.OpZone)
{
var zone = BitConverter.ToUInt16(data, 4);
if (zone != _last_zone)
{
_last_zone = zone;
ResetContentItems();
}
}
// save the queen critical engagement
else if (DcConfig.Packet.OpCe != 0 && opcode == DcConfig.Packet.OpCe)
{
// 0[4] timestamp
// 4[2] mmss
// 6[2] ?
// 8[1] code
// 9[1] members
// 10[1] status 0=end, 1=register, 2=entry, 3=progress
// 12[1] progress percentage
if (_stq_type == DcContent.SaveTheQueenType.No)
{
if (IsFateForSouthernBozja(_last_fate))
_stq_type = DcContent.SaveTheQueenType.Bozja;
else if (IsFateForZadnor(_last_fate))
_stq_type = DcContent.SaveTheQueenType.Zadnor;
else
_stq_type = DcContent.SaveTheQueenType.Zadnor;
}
var ce = data[8] + DcContent.SaveTheQueenTypeToCeBase(_stq_type);
var stat = data[10];
var fate = DcContent.GetFate(ce);
if (stat == 0 /* || data[10] == 3 */)
{
if (DcContent.Missions.ContainsKey(ce))
DcContent.Missions.Remove(ce);
TraceCe(ce, false, fate);
}
else if (stat == 1 || stat == 2)
{
var withlog = false;
if (!DcContent.Missions.ContainsKey(ce))
{
withlog = true;
DcContent.Missions.Add(ce, 0);
if (DcConfig.Duty.Fates[DcConfig.Duty.ActiveFate].Selected.Contains(ce))
{
PlayEffectSoundFate();
NotifyFate(fate);
_overlay.PlayFate(fate);
}
}
TraceCe(ce, withlog, fate, stat == 1 ? "R" : "E");
}
else if (stat == 3)
{
if (!DcContent.Missions.ContainsKey(ce))
DcContent.Missions.Add(ce, 0);
TraceCe(ce, false, fate, data[12].ToString());
}
}
}
//
public void ZoneChanged(uint zone_id, string zone_name)
{
//_overlay.PlayNone();
_stq_type =
(zone_id == 920) ? DcContent.SaveTheQueenType.Bozja :
(zone_id == 921) ? DcContent.SaveTheQueenType.Zadnor :
DcContent.SaveTheQueenType.No;
#if false
LogInstance(10025, $"{zone_name} ({zone_id})");
if (DcConfig.DebugEnable)
LogDebug("Zone: {0}", zone_id);
#endif
// Probably receive FATE auto end command before changing zone
// No end data found: logout, critical engagement -> have to reset
if (DcConfig.Packet.OpZone == 0)
ResetContentItems();
}
//
private void WriteLog(Color color, int catkey, int fmtkey, params object[] prms)
{
string category = Locale.Text(catkey);
string format = Locale.Text(fmtkey);
Logger.WriteCategory(color, category, format, prms);
}
//
private void TraceFate(ushort code, bool withlog, DcContent.Fate fate, int progress = -1)
{
// TODO: check area
int key, subs;
if (_stq_type != DcContent.SaveTheQueenType.No || IsSkirmishFate(code))
{
key = 24;
subs = 4;
}
else
{
key = 23;
subs = 3;
}
if (withlog)
WriteLog(Color.Black, key, 10001, fate.Name);
WorkerAct.Invoker(() => lstContents.TreatItemFate(code, subs, progress, fate.Name));
}
//
private void TraceCe(int code, bool withlog, DcContent.Fate fate, string progress = null)
{
if (withlog)
WriteLog(Color.Black, 25, 10001, fate.Name);
WorkerAct.Invoker(() => lstContents.TreatItemCe(code, 5, progress, fate.Name));
}
//
private void UpdateTraceInstance(int imageindex, int count, string insname)
{
WorkerAct.Invoker(() => lstContents.TreatItemInstance(imageindex, count, insname));
}
//
private void TraceMatchInstance(DcContent.Instance instance)
{
WriteLog(Color.Black, 22, 10003, instance.Name);
UpdateTraceInstance(6, 0, instance.Name);
}
//
private void TraceEnterInstance(DcContent.Instance instance)
{
WriteLog(Color.Black, 22, 10004, instance.Name);
UpdateTraceInstance(2, 0, instance.Name);
}
//
private void TraceEntryInstance(List<int> instances)
{
var insnames = string.Join("/", instances.ToArray());
WriteLog(Color.Black, 22, 10002, insnames);
UpdateTraceInstance(7, instances.Count, insnames);
}
//
private void TraceMatchRoulette(DcContent.Roulette roulette)
{
WriteLog(Color.Black, 22, 10003, roulette.Name);
UpdateTraceInstance(6, 0, roulette.Name);
}
//
private void TraceEntryRoulette(DcContent.Roulette roulette)
{
WriteLog(Color.Black, 22, 10002, roulette.Name);
UpdateTraceInstance(1, 0, roulette.Name);
}
//
public void UpdateFates()
{
var fs = DcConfig.Duty.Fates[DcConfig.Duty.ActiveFate];
treeFates.Nodes.Clear();
fs.MakeSelects(true);
_is_lock_fate = true;
foreach (var a in DcContent.Areas)
{
var n = treeFates.Nodes.Add(a.Value.Name);
n.Tag = a.Key + 100000;
if (fs.Selected.Contains((int)n.Tag))
{
n.Checked = true;
n.Expand();
}
foreach (var f in a.Value.Fates)
{
var name = f.Value.Name;
var node = n.Nodes.Add(name);
node.Tag = f.Key;
if (fs.Selected.Contains((int)node.Tag))
{
node.Checked = true;
if (!n.IsExpanded)
n.Expand();
}
}
}
MakeFatesSelection();
_is_lock_fate = false;
}
//
private void MakeFatesSelection(bool makeline = false)
{
var fs = DcConfig.Duty.Fates[DcConfig.Duty.ActiveFate];
fs.Selected.Clear();
FateSelectionMakingLoop(treeFates.Nodes);
if (makeline)
fs.MakeLine();
}
//
private void FateSelectionMakingLoop(TreeNodeCollection nodes)
{
var fs = DcConfig.Duty.Fates[DcConfig.Duty.ActiveFate];
foreach (TreeNode n in nodes)
{
if (n.Checked)
fs.Selected.Add((int)n.Tag);
FateSelectionMakingLoop(n.Nodes);
}
}
private void CboDataset_SelectedIndexChanged(object sender, EventArgs e)
{
if (!DcConfig.PluginEnable)
return;
var l = (string)cboDataset.SelectedItem;
if (!string.IsNullOrWhiteSpace(l) && !l.Equals(DcConfig.Duty.Language) && DcContent.ReadContent(l))
{
lblCurrentDataSet.Text = DcContent.DisplayLanguage;
SaveConfig();
if (DcConfig.DataRemoteUpdate)
Updater.CheckNewVersion();
UpdateFates();
}
}
private void CboPacketset_SelectedIndexChanged(object sender, EventArgs e)
{
if (!DcConfig.PluginEnable)
return;
if (cboPacketset.SelectedIndex >= _packet_list.Count)
return;
var p = _packet_list.ElementAt(cboPacketset.SelectedIndex);
var n = p.Key;
if (!string.IsNullOrWhiteSpace(n) && !n.Equals(DcConfig.Duty.PacketSet) && DcConfig.ReadPacket(n))
{
SaveConfig();
if (!n.Equals(DcConfig.PacketConfig.DefaultSetNameCustom))
{
// check update and save
RemotePacketUpdate(n);
}
}
}
private void TreeFates_AfterCheck(object sender, TreeViewEventArgs e)
{
if (!DcConfig.PluginEnable)
return;
if (_is_lock_fate)
return;
_is_lock_fate = true;
if (((int)e.Node.Tag) > 100000)
{
foreach (TreeNode n in e.Node.Nodes)
n.Checked = e.Node.Checked;
}
else
{
if (!e.Node.Checked)
e.Node.Parent.Checked = false;
else
{
var f = true;
foreach (TreeNode n in e.Node.Parent.Nodes)
f &= n.Checked;
e.Node.Parent.Checked = f;
}
}
MakeFatesSelection(true);
SaveConfig();
_is_lock_fate = false;
}
//
private void ChangeFatePreset(int index)
{
if (!DcConfig.PluginEnable)
return;
if (index >= 0 && index < 4)
{
DcConfig.Duty.ActiveFate = index;
UpdateFates();
SaveConfig();
}
}
private void RdoFatePreset1_CheckedChanged(object sender, EventArgs e)
{
ChangeFatePreset(0);
}
private void RdoFatePreset2_CheckedChanged(object sender, EventArgs e)
{
ChangeFatePreset(1);
}
private void RdoFatePreset3_CheckedChanged(object sender, EventArgs e)
{
ChangeFatePreset(2);
}
private void RdoFatePreset4_CheckedChanged(object sender, EventArgs e)
{
ChangeFatePreset(3);
}
private void ChkEnableOverlay_CheckedChanged(object sender, EventArgs e)
{
if (!DcConfig.PluginEnable)
return;
progbOverlayTransparent.Enabled = chkEnableOverlay.Checked;
btnOverlayDimming.Enabled = chkEnableOverlay.Checked;
if (chkEnableOverlay.Checked)
_overlay.Show();
else
_overlay.Hide();
DcConfig.Duty.EnableOverlay = chkEnableOverlay.Checked;
SaveConfig();
}
private void ProgbOverlayTransparent_Click(object sender, EventArgs e)
{
}
private void BtnOverlayDimming_Click(object sender, EventArgs e)
{
_overlay.StartBlink();
}
private void ChkOverlayClickThru_CheckedChanged(object sender, EventArgs e)
{
if (!DcConfig.PluginEnable)
return;
DcConfig.Duty.OverlayClickThru = chkOverlayClickThru.Checked;
_overlay.SetClickThruStatus(chkOverlayClickThru.Checked);
SaveConfig();
}
private void ChkEnableSound_CheckedChanged(object sender, EventArgs e)
{
if (!DcConfig.PluginEnable)
return;
txtSoundInstance.Enabled = chkEnableSound.Checked;
btnSoundFindInstance.Enabled = chkEnableSound.Checked;
btnSoundPlayInstance.Enabled = chkEnableSound.Checked;
txtSoundFate.Enabled = chkEnableSound.Checked;
btnSoundFindFate.Enabled = chkEnableSound.Checked;
btnSoundPlayFate.Enabled = chkEnableSound.Checked;
DcConfig.Duty.EnableSound = chkEnableSound.Checked;
SaveConfig();
}
//
private void PlayEffectSoundFate()
{
if (DcConfig.Duty.EnableSound)
WorkerAct.PlayEffectSound(DcConfig.Duty.SoundFateFile, DcConfig.Duty.SoundFateVolume);
}
//
private void PlayEffecSoundInstance()
{
if (DcConfig.Duty.EnableSound)
WorkerAct.PlayEffectSound(DcConfig.Duty.SoundInstanceFile, DcConfig.Duty.SoundInstanceVolume);
}
private void BtnSoundPlayInstance_Click(object sender, EventArgs e)
{
if (!DcConfig.PluginEnable)
return;
PlayEffecSoundInstance();
}
private void BtnSoundPlayFate_Click(object sender, EventArgs e)
{
if (!DcConfig.PluginEnable)
return;
PlayEffectSoundFate();
}
//
private string SoundFileOpenDialog()
{
string filename = (string)WorkerAct.Invoker(new WorkerAct.ObjectReturnerDelegate(() =>
{
var dg = new OpenFileDialog
{
Title = Locale.Text(101),
DefaultExt = "wav",
Filter = Locale.Text(102)
};
return (dg.ShowDialog() == DialogResult.OK) ? dg.FileName : null;
}));
return filename;
}
private void BtnSoundFindInstance_Click(object sender, EventArgs e)
{
if (!DcConfig.PluginEnable)
return;
string filename = SoundFileOpenDialog();
DcConfig.Duty.SoundInstanceFile = string.IsNullOrEmpty(filename) ? string.Empty : filename;
txtSoundInstance.Text = DcConfig.Duty.SoundInstanceFile;
SaveConfig();
}
private void BtnSoundFindFate_Click(object sender, EventArgs e)
{
if (!DcConfig.PluginEnable)
return;
string filename = SoundFileOpenDialog();
DcConfig.Duty.SoundFateFile = string.IsNullOrEmpty(filename) ? string.Empty : filename;
txtSoundFate.Text = DcConfig.Duty.SoundFateFile;
SaveConfig();
}
private async void BtnTestNotify_Click(object sender, EventArgs e)
{
if (!DcConfig.PluginEnable)
return;
string s = Locale.Text(103);
if (DcConfig.Duty.UseNotifyLine)
await NotifyUsingLine(s);
if (DcConfig.Duty.UseNotifyTelegram)
NotifyUsingTelegram(s);
if (DcConfig.Duty.UseNotifyDiscordWebhook)
await NotifyUsingDiscordWebhook(s);
}
//
private void SendNotify(string s)
{
if (DcConfig.Duty.UseNotifyLine)
NotifyUsingLine(s).Wait();
if (DcConfig.Duty.UseNotifyTelegram)
NotifyUsingTelegram(s);
if (DcConfig.Duty.UseNotifyDiscordWebhook)
NotifyUsingDiscordWebhook(s).Wait();
}
//
private void NotifyFate(DcContent.Fate f)
{
if (!DcConfig.Duty.EnableNotify)
return;
string s = Locale.Text(10005, f.Name);
SendNotify(s);
}
//
private void NotifyMatch(string name)
{
if (!DcConfig.Duty.EnableNotify)
return;
string s = Locale.Text(10003, name);
SendNotify(s);
}
private void ChkUseNotifyLine_CheckedChanged(object sender, EventArgs e)
{
if (!DcConfig.PluginEnable)
return;
DcConfig.Duty.UseNotifyLine = chkUseNotifyLine.Checked;
txtLineToken.Enabled = chkUseNotifyLine.Checked;
btnTestNotify.Enabled = DcConfig.Duty.EnableNotify;
SaveConfig();
}
private void LblLineNotifyBotLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
if (!DcConfig.PluginEnable)
return;
Process.Start(lblLineNotifyBotLink.Text);
}
private void TxtLineToken_KeyDown(object sender, KeyEventArgs e)
{
if (!DcConfig.PluginEnable)
return;
if (e.KeyCode == Keys.Enter)
{
DcConfig.Duty.NotifyLineToken = txtLineToken.Text;
SaveConfig();
}
btnTestNotify.Enabled = true;
}
//
internal async Task NotifyUsingLine(string mesg)
{
if (txtLineToken.TextLength == 0)
return;
if (!txtLineToken.Text.Equals(DcConfig.Duty.NotifyLineToken))
{
DcConfig.Duty.NotifyLineToken = txtLineToken.Text;
SaveConfig();
}
var hc = new HttpClient();
hc.DefaultRequestHeaders.Add("Authorization", $"Bearer {DcConfig.Duty.NotifyLineToken}");
var param = new Dictionary<string, string>
{
{ "message", mesg }
};
await hc.PostAsync("https://notify-api.line.me/api/notify",
new FormUrlEncodedContent(param)).ConfigureAwait(false);
}
//
private void ChkUseNotifyTelegram_CheckedChanged(object sender, EventArgs e)
{
if (!DcConfig.PluginEnable)
return;
DcConfig.Duty.UseNotifyTelegram = chkUseNotifyTelegram.Checked;
txtTelegramId.Enabled = chkUseNotifyTelegram.Checked;
txtTelegramToken.Enabled = chkUseNotifyTelegram.Checked;
btnTestNotify.Enabled = DcConfig.Duty.EnableNotify;
SaveConfig();
}
private void TxtTelegramId_KeyDown(object sender, KeyEventArgs e)
{
if (!DcConfig.PluginEnable)
return;
if (e.KeyCode == Keys.Enter)
{
DcConfig.Duty.NotifyTelegramId = txtTelegramId.Text;
SaveConfig();
}
btnTestNotify.Enabled = true;
}
private void TxtTelegramToken_KeyDown(object sender, KeyEventArgs e)
{
if (!DcConfig.PluginEnable)
return;
if (e.KeyCode == Keys.Enter)
{
DcConfig.Duty.NotifyTelegramToken = txtTelegramToken.Text;
SaveConfig();
}
btnTestNotify.Enabled = true;
}
//
private static string EncodeJsonChars(string text)
{
return text.Replace("\b", "\\\b")
.Replace("\f", "\\\f")
.Replace("\n", "\\\n")
.Replace("\r", "\\\r")
.Replace("\t", "\\\t")
.Replace("\"", "\\\"")
.Replace("\\", "\\\\");
}
//
private bool NotifyUsingTelegram(string mesg)
{
if (txtTelegramId.TextLength == 0 || txtTelegramToken.TextLength == 0)
return false;
if (!txtTelegramId.Text.Equals(DcConfig.Duty.NotifyTelegramId))
{
DcConfig.Duty.NotifyTelegramId = txtTelegramId.Text;
SaveConfig();
}
if (!txtTelegramToken.Text.Equals(DcConfig.Duty.NotifyTelegramToken))
{
DcConfig.Duty.NotifyTelegramToken = txtTelegramToken.Text;
SaveConfig();
}
// https://codingman.tistory.com/41
var json = string.Format("{{\"chat_id\":\"{0}\", \"text\":\"{1}\"}}",
DcConfig.Duty.NotifyTelegramId, EncodeJsonChars(mesg));
var jbin = Encoding.UTF8.GetBytes(json);
var url = string.Format("https://api.telegram.org/bot{0}/sendMessage", DcConfig.Duty.NotifyTelegramToken);
HttpWebRequest req = WebRequest.Create(new Uri(url)) as HttpWebRequest;
req.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
req.Timeout = 30 * 1000;
req.Method = "POST";
req.ContentType = "application/json";
using (var st = req.GetRequestStream())
{
st.Write(jbin, 0, jbin.Length);
st.Flush();
}
HttpWebResponse res = null;
try
{
res = req.GetResponse() as HttpWebResponse;
if (res.StatusCode == HttpStatusCode.OK)
{
string ss = null;
using (var st = res.GetResponseStream())
{
using (var rdr = new StreamReader(st, Encoding.UTF8))
ss = rdr.ReadToEnd();
}
if (0 < ss.IndexOf("\"ok\":true"))
return true;
else
return false;
}
else
{
// http status is not ok
return false;
}
}
catch
{
// ???
return false;
}
finally
{
if (res != null)
res.Close();
}
}
private void ChkUseNotifyDiscowk_CheckedChanged(object sender, EventArgs e)
{
if (!DcConfig.PluginEnable)
return;
DcConfig.Duty.UseNotifyDiscordWebhook = chkUseNotifyDiscowk.Checked;
txtDiscowkUrl.Enabled = chkUseNotifyDiscowk.Checked;
btnTestNotify.Enabled = DcConfig.Duty.EnableNotify;
SaveConfig();
}
private void TxtDiscowkUrl_KeyDown(object sender, KeyEventArgs e)
{
if (!DcConfig.PluginEnable)
return;
if (e.KeyCode == Keys.Enter)
{
if (!IsValidDiscwkUrl(txtDiscowkUrl.Text))
{
Logger.E(342);
return;
}
DcConfig.Duty.NotifyDiscordWebhookUrl = txtDiscowkUrl.Text;
SaveConfig();
}
btnTestNotify.Enabled = true;
}
private void ChkDiscowkTts_CheckedChanged(object sender, EventArgs e)
{
if (!DcConfig.PluginEnable)
return;
DcConfig.Duty.NotifyDiscordWebhookTts = chkDiscowkTts.Checked;
btnTestNotify.Enabled = DcConfig.Duty.EnableNotify;
SaveConfig();
}
private static bool IsValidDiscwkUrl(string url)
{
url = url.ToLower();
return url.StartsWith("https://discord.com/api/webhooks/");
}
//
internal async Task NotifyUsingDiscordWebhook(string mesg)
{
if (txtDiscowkUrl.TextLength == 0)
return;
if (!IsValidDiscwkUrl(txtDiscowkUrl.Text))
{
Logger.E(342);
return;
}
if (!txtDiscowkUrl.Text.Equals(DcConfig.Duty.NotifyDiscordWebhookUrl))
{
DcConfig.Duty.NotifyDiscordWebhookUrl = txtDiscowkUrl.Text;
SaveConfig();
}
var hc = new HttpClient();
var param = new Dictionary<string, string>
{
{ "content", mesg },
{ "tts", DcConfig.Duty.NotifyDiscordWebhookTts.ToString() },
};
await hc.PostAsync(DcConfig.Duty.NotifyDiscordWebhookUrl,
new FormUrlEncodedContent(param)).ConfigureAwait(false);
}
//
private void PacketFinderResetUi(bool is_enable)
{
if (!is_enable)
{
btnPacketStart.Text = Locale.Text(10007);
btnPacketStart.BackColor = Color.Transparent;
}
else
{
btnPacketStart.Text = Locale.Text(10008);
btnPacketStart.BackColor = Color.Salmon;
}
btnPacketApply.Visible = is_enable;
btnPacketApply.Enabled = is_enable;
lstPacketInfo.Enabled = is_enable;
txtPacketInfo.Enabled = is_enable;
txtPacketDescription.Enabled = is_enable;
lstBozjaInfo.Enabled = is_enable;
}
//
private void PacketFindClearUi(DcConfig.PacketConfig newpk)
{
//
lblPacketVersion.Text = newpk.Version.ToString();
txtPacketDescription.Text = newpk.Description;
lstBozjaInfo.Items.Clear();
// FATE
lstPacketInfo.Items[0].SubItems[1].Text = DcConfig.Packet.OpFate.ToString();
lstPacketInfo.Items[0].SubItems[2].Text = "";
lstPacketInfo.Items[0].SubItems[3].Text = newpk.OpFate.ToString();
// Duty
lstPacketInfo.Items[1].SubItems[1].Text = DcConfig.Packet.OpDuty.ToString();
lstPacketInfo.Items[1].SubItems[2].Text = "";
lstPacketInfo.Items[1].SubItems[3].Text = newpk.OpDuty.ToString();
// Match
lstPacketInfo.Items[2].SubItems[1].Text = DcConfig.Packet.OpMatch.ToString();
lstPacketInfo.Items[2].SubItems[2].Text = "";
lstPacketInfo.Items[2].SubItems[3].Text = newpk.OpMatch.ToString();
// Instance
lstPacketInfo.Items[3].SubItems[1].Text = DcConfig.Packet.OpInstance.ToString();
lstPacketInfo.Items[3].SubItems[2].Text = "";
lstPacketInfo.Items[3].SubItems[3].Text = newpk.OpInstance.ToString();
// Zone
lstPacketInfo.Items[4].SubItems[1].Text = DcConfig.Packet.OpZone.ToString();
lstPacketInfo.Items[4].SubItems[2].Text = "";
lstPacketInfo.Items[4].SubItems[3].Text = newpk.OpZone.ToString();
// Bozja
lstPacketInfo.Items[5].SubItems[1].Text = DcConfig.Packet.OpCe.ToString();
lstPacketInfo.Items[5].SubItems[2].Text = "";
lstPacketInfo.Items[5].SubItems[3].Text = newpk.OpCe.ToString();
}
private void BtnPacketStart_Click(object sender, EventArgs e)
{
if (!_is_packet_finder)
{
_new_packet = new DcConfig.PacketConfig(DateTime.Now);
PacketFindClearUi(_new_packet);
}
_is_packet_finder = !_is_packet_finder;
PacketFinderResetUi(_is_packet_finder);
}
private void BtnPacketApply_Click(object sender, EventArgs e)
{
var ret = (DialogResult)WorkerAct.Invoker(new WorkerAct.ObjectReturnerDelegate(() =>
{
var r = MessageBox.Show(Locale.Text(10022), Locale.Text(0), MessageBoxButtons.YesNo, MessageBoxIcon.Question);
return r;
}));
if (ret == DialogResult.Yes)
{
var newfilename = DcConfig.BuildPacketFileName(DcConfig.PacketConfig.DefaultSetNameCustom);
_new_packet.Description = txtPacketDescription.Text;
_new_packet.Save(newfilename);
_is_packet_finder = false;
PacketFinderResetUi(false);
// select custom
DcConfig.Duty.PacketSet = DcConfig.PacketConfig.DefaultSetNameCustom;
RefreshPacketList();
}
}
private void LstPacketInfo_SelectedIndexChanged(object sender, EventArgs e)
{
if (lstPacketInfo.SelectedIndices.Count != 1)
return;
int m;
switch (lstPacketInfo.SelectedIndices[0])
{
case 0: m = 10010; break;
case 1: m = 10011; break;
case 2: m = 10011; break;
case 3: m = 10011; break;
case 4: m = 10026; break;
case 5: m = 10014; break;
default: m = 10015; break;
}
txtPacketInfo.Text = Locale.Text(m);
}
private void LstPacketInfo_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (lstPacketInfo.SelectedIndices.Count != 1)
return;
var v = int.MaxValue;
switch (lstPacketInfo.SelectedIndices[0])
{
case 0:
v = _new_packet.OpFate = DcConfig.Packet.OpFate;
break;
case 1:
v = _new_packet.OpDuty = DcConfig.Packet.OpDuty;
break;
case 2:
v = _new_packet.OpMatch = DcConfig.Packet.OpMatch;
break;
case 3:
v = _new_packet.OpInstance = DcConfig.Packet.OpInstance;
break;
case 4:
v = _new_packet.OpZone = DcConfig.Packet.OpZone;
break;
case 5:
v = _new_packet.OpCe = DcConfig.Packet.OpCe;
break;
}
if (v != int.MaxValue)
{
lstPacketInfo.SelectedItems[0].SubItems[2].Text = Locale.Text(10024);
lstPacketInfo.SelectedItems[0].SubItems[3].Text = v.ToString();
}
}
private void LstBozjaInfo_SelectedIndexChanged(object sender, EventArgs e)
{
if (lstBozjaInfo.SelectedItems.Count != 1)
return;
ushort opcode = (ushort)lstBozjaInfo.SelectedItems[0].Tag;
_new_packet.OpCe = opcode;
lstPacketInfo.Items[5].SubItems[2].Text = Locale.Text(10023);
lstPacketInfo.Items[5].SubItems[3].Text = _new_packet.OpCe.ToString();
}
private void LstBozjaInfo_MouseDoubleClick(object sender, MouseEventArgs e)
{
}
// middle la noscea
private static readonly ushort[] _fates_middle_la_noscea =
{
553, 649, 687, 688, 693, 717,
220, 221, 222, 223, 225, 226, 227, 229, 231, 233, 235, 237, 238, 239, 240,
1387,
};
// southern bozja front
private static readonly ushort[] _fates_southern_bojza =
{
1597, 1598, 1599,
1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609,
1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619,
1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628,
};
// zadnor
private static readonly ushort[] _fates_zadnor =
{
1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724,
1725, 1726, 1727, 1728, 1729, 1730, 1731, 1732,
1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742,
};
//
private bool IsFateInFindList(ushort code)
{
return
_fates_middle_la_noscea.Contains(code) ||
_fates_southern_bojza.Contains(code) ||
_fates_zadnor.Contains(code);
}
//
private bool IsSkirmishFate(ushort code)
{
return
_fates_southern_bojza.Contains(code) ||
_fates_zadnor.Contains(code);
}
//
private bool IsFateForSouthernBozja(ushort code)
{
return _fates_southern_bojza.Contains(code);
}
//
private bool IsFateForZadnor(ushort code)
{
return _fates_zadnor.Contains(code);
}
//
private void PacketFinderHandler(byte[] message)
{
var opcode = BitConverter.ToUInt16(message, 18);
var data = message.Skip(32).ToArray();
// fate
if (_new_packet.OpFate == 0 && data.Length > 4 && data[0] == 0x3E)
{
var cc = BitConverter.ToUInt16(data, 4);
if (IsFateInFindList(cc) && _new_packet.OpFate != opcode)
{
_new_packet.OpFate = opcode;
WorkerAct.Invoker(() =>
{
lstPacketInfo.Items[0].SubItems[2].Text = Locale.Text(10016);
lstPacketInfo.Items[0].SubItems[3].Text = _new_packet.OpFate.ToString();
});
_last_fate = cc;
return;
}
}
// duty
if (_new_packet.OpDuty == 0 && data.Length > 12)
{
var rcode = data[8];
if (rcode == 0)
{
// The Steps of Fath (83)
short m = BitConverter.ToInt16(data, 12);
if (m == 83 && _new_packet.OpDuty != opcode)
{
_new_packet.OpDuty = opcode;
WorkerAct.Invoker(() =>
{
lstPacketInfo.Items[1].SubItems[2].Text = Locale.Text(10016);
lstPacketInfo.Items[1].SubItems[3].Text = _new_packet.OpDuty.ToString();
});
return;
}
}
}
// match
if (_new_packet.OpMatch == 0 && data.Length > 20)
{
var rcode = data[2];
if (rcode == 0)
{
// The Steps of Fath (83)
short m = BitConverter.ToInt16(data, 20);
if (m == 83 && _new_packet.OpMatch != opcode)
{
_new_packet.OpMatch = opcode;
WorkerAct.Invoker(() =>
{
lstPacketInfo.Items[2].SubItems[2].Text = Locale.Text(10016);
lstPacketInfo.Items[2].SubItems[3].Text = _new_packet.OpMatch.ToString();
});
return;
}
}
}
// instance
if (_new_packet.OpInstance == 0 && data.Length >= 16)
{
// The Steps of Fath (83)
short m = BitConverter.ToInt16(data, 0);
short u = BitConverter.ToInt16(data, 2);
if (m == 83 && u == 0 && _new_packet.OpInstance != opcode)
{
_new_packet.OpInstance = opcode;
WorkerAct.Invoker(() =>
{
lstPacketInfo.Items[3].SubItems[2].Text = Locale.Text(10016);
lstPacketInfo.Items[3].SubItems[3].Text = _new_packet.OpInstance.ToString();
});
return;
}
}
// zone
if (_new_packet.OpZone == 0 && data.Length == 16)
{
// Middle La Noscea (134)
var h = BitConverter.ToUInt32(data, 0);
var z = BitConverter.ToUInt16(data, 4);
if (h == 0 && z == 134)
{
_new_packet.OpZone = opcode;
WorkerAct.Invoker(() =>
{
lstPacketInfo.Items[4].SubItems[2].Text = Locale.Text(10016);
lstPacketInfo.Items[4].SubItems[3].Text = _new_packet.OpZone.ToString();
});
return;
}
}
// critical engagement
if (data.Length >= 12 && _stq_type != DcContent.SaveTheQueenType.No)
{
// 0[4] timestamp
// 4[2] mmss
// 6[2] ?
// 8[1] code
// 9[1] members
// 10[1] status 0=end, 1=register, 2=entry, 3=progress
// 12[1] progress percentage
var code = data[8];
if (code < 0 || code > 15)
{
// not ce
return;
}
var ok = false;
var mem = data[9];
var stat = data[10];
var prg = data[12];
/*
if (stat == 0)
{
// end. other conditions unknown
ok = true;
}
else*/
if (stat == 1)
{
// register. progress must be 0
if (mem >= 0 && mem <= 48 && prg == 0)
ok = true;
}
else if (stat == 2)
{
// entry. progress must be 0
if (mem >= 0 && mem <= 48 && prg == 0)
ok = true;
}
else if (stat == 3)
{
// progress. progress must be in 1~99
if (mem > 0 && mem <= 48 && prg >= 1 && prg < 100)
ok = true;
}
if (ok)
{
if (_stq_type == DcContent.SaveTheQueenType.No)
{
if (IsFateForSouthernBozja(_last_fate))
_stq_type = DcContent.SaveTheQueenType.Bozja;
else if (IsFateForZadnor(_last_fate))
_stq_type = DcContent.SaveTheQueenType.Zadnor;
else
_stq_type = DcContent.SaveTheQueenType.Zadnor;
}
var ce = DcContent.GetFate(code + DcContent.SaveTheQueenTypeToCeBase(_stq_type));
var li = new ListViewItem(new string[]
{
ce.Name,
DcContent.CeStatusToString(stat),
mem.ToString(),
prg.ToString()
})
{
Tag = opcode
};
WorkerAct.Invoker(() =>
{
lstBozjaInfo.Items.Add(li);
lstBozjaInfo.EnsureVisible(lstBozjaInfo.Items.Count - 1);
});
}
}
}
private void RemotePacketUpdate(string name)
{
// need to resign using thread -> blocked by network troubles
if (!DcConfig.DataRemoteUpdate)
return;
var ns = Updater.CheckNewPacket(name);
if (!string.IsNullOrWhiteSpace(ns))
{
var pk = DcConfig.PacketConfig.ParseString(ns);
if (pk.Version > DcConfig.Packet.Version)
{
DcConfig.Packet.Version = pk.Version;
DcConfig.Packet.Description = pk.Description;
DcConfig.Packet.OpFate = pk.OpFate;
DcConfig.Packet.OpDuty = pk.OpDuty;
DcConfig.Packet.OpMatch = pk.OpMatch;
DcConfig.Packet.OpInstance = pk.OpInstance;
DcConfig.Packet.OpZone = pk.OpZone;
DcConfig.Packet.OpCe = pk.OpCe;
var nfn = DcConfig.BuildPacketFileName(name);
pk.Save(nfn);
Logger.I(33, pk.Version, pk.Description);
//
_packet_list.Remove(name);
_packet_list.Add(name, pk.Description);
RefreshPacketList(false);
}
}
}
private void RefreshDatasetList()
{
// quick description read?
cboDataset.Items.Clear();
DirectoryInfo di = new DirectoryInfo(DcConfig.DataPath);
foreach (var fi in di.GetFiles("DcDuty-*.json"))
{
var s = fi.Name.Substring(7, fi.Name.Length - 7 - 5);
var n = cboDataset.Items.Add(s);
if (s.Equals(DcConfig.Duty.Language))
cboDataset.SelectedIndex = n;
}
}
private void RefreshPacketList(bool reload_file_info = true)
{
if (reload_file_info)
{
_packet_list.Clear();
DirectoryInfo di = new DirectoryInfo(DcConfig.DataPath);
foreach (var fi in di.GetFiles("DcPacket-*.config"))
{
var name = fi.Name.Substring(9, fi.Name.Length - 9 - 7);
var db = new ThirdParty.LineDb(fi.FullName, Encoding.UTF8, false);
var desc = db.Get("Description", null);
if (desc == null)
{
// config file was for below version 9
_packet_list.Add(name, name);
}
else
{
_packet_list.Add(name, desc);
}
}
}
cboPacketset.Items.Clear();
foreach (var i in _packet_list)
{
var n = cboPacketset.Items.Add(i.Value);
if (i.Key.Equals(DcConfig.Duty.PacketSet))
cboPacketset.SelectedIndex = n;
}
}
private void BtnResetContentList_Click(object sender, EventArgs e)
{
lstContents.ResetContentItems();
}
public void ResetContentItems()
{
WorkerAct.Invoker(() => lstContents.ResetContentItems());
}
}
}