Fix bugs after version 9 (#17)

* Fix Nier3 instance id

* Packet list correctly display after packet updated

* Plugin update checker
This commit is contained in:
ksh 2021-06-18 21:08:43 +09:00 committed by GitHub
parent 879b01a363
commit 5a9452d378
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 563 additions and 161 deletions

View file

@ -536,6 +536,8 @@
"757": "the Navel (Unreal)", "757": "the Navel (Unreal)",
"758": "Eden`s Promise: Eternity", "758": "Eden`s Promise: Eternity",
"759": "Eden`s Promise: Eternity (Savage)", "759": "Eden`s Promise: Eternity (Savage)",
"760": "Delubrum Reginae",
"761": "Delubrum Reginae (Savage)",
"762": "Castrum Marinum", "762": "Castrum Marinum",
"763": "Castrum Marinum (Extreme)", "763": "Castrum Marinum (Extreme)",
"766": "Novice Mahjong (Quick Ranked Match)", "766": "Novice Mahjong (Quick Ranked Match)",
@ -548,13 +550,11 @@
"773": "Ocean Fishing", "773": "Ocean Fishing",
"774": "Ocean Fishing", "774": "Ocean Fishing",
"775": "Ocean Fishing", "775": "Ocean Fishing",
"760": "Delubrum Reginae",
"761": "Delubrum Reginae (Savage)",
"777": "Paglth'an", "777": "Paglth'an",
"778": "Zadnor", "778": "Zadnor",
"779": "the Tower at Paradigm's Breach",
"781": "The Cloud Deck", "781": "The Cloud Deck",
"782": "The Cloud Deck (Extreme)", "782": "The Cloud Deck (Extreme)"
"799": "the Tower at Paradigm's Breach"
}, },
"areas": { "areas": {
"134": { "134": {

View file

@ -552,9 +552,9 @@
"775": "Auf großer Fahrt", "775": "Auf großer Fahrt",
"777": "Die Goldene Ebene von Paglth'an", "777": "Die Goldene Ebene von Paglth'an",
"778": "Zadnor-Hochebene", "778": "Zadnor-Hochebene",
"779": "Der Turm, Paradigmenbrecher",
"781": "Diamantblitz - Entfesselung", "781": "Diamantblitz - Entfesselung",
"782": "Diamantblitz - Trauma", "782": "Diamantblitz - Trauma"
"799": "Der Turm, Paradigmenbrecher"
}, },
"areas": { "areas": {
"134": { "134": {

View file

@ -536,6 +536,8 @@
"757": "幻タイタン討滅戦", "757": "幻タイタン討滅戦",
"758": "希望の園エデン再生編4", "758": "希望の園エデン再生編4",
"759": "希望の園エデン零式再生編4", "759": "希望の園エデン零式再生編4",
"760": "グンヒルド・ディルーブラム",
"761": "グンヒルド・ディルーブラム零式",
"762": "エメラルドウェポン破壊作戦", "762": "エメラルドウェポン破壊作戦",
"763": "極エメラルドウェポン破壊作戦", "763": "極エメラルドウェポン破壊作戦",
"766": "ドマ式麻雀:東風戦一般卓(段位変動有り)", "766": "ドマ式麻雀:東風戦一般卓(段位変動有り)",
@ -548,8 +550,6 @@
"773": "オーシャンフィッシング", "773": "オーシャンフィッシング",
"774": "オーシャンフィッシング", "774": "オーシャンフィッシング",
"775": "オーシャンフィッシング", "775": "オーシャンフィッシング",
"760": "グンヒルド・ディルーブラム",
"761": "グンヒルド・ディルーブラム零式",
"777": "黄金平原 パガルザン", "777": "黄金平原 パガルザン",
"778": "ザトゥノル高原", "778": "ザトゥノル高原",
"779": "希望ノ砲台:「塔」", "779": "希望ノ砲台:「塔」",

View file

@ -513,6 +513,8 @@
"757": "환 타이탄 토벌전", "757": "환 타이탄 토벌전",
"758": "희망의 낙원 에덴: 재생편 4", "758": "희망의 낙원 에덴: 재생편 4",
"759": "희망의 낙원 에덴: 재생편(영웅) 4", "759": "희망의 낙원 에덴: 재생편(영웅) 4",
"760": "Delubrum Reginae",
"761": "Delubrum Reginae (영웅)",
"762": "에메랄드 웨폰 파괴작전", "762": "에메랄드 웨폰 파괴작전",
"763": "극 에메랄드 웨폰 파괴작전", "763": "극 에메랄드 웨폰 파괴작전",
"766": "도마식마작: 동풍전 일반 탁자 (단위변동있음)", "766": "도마식마작: 동풍전 일반 탁자 (단위변동있음)",
@ -525,8 +527,6 @@
"773": "먼바다 낚시", "773": "먼바다 낚시",
"774": "먼바다 낚시", "774": "먼바다 낚시",
"775": "먼바다 낚시", "775": "먼바다 낚시",
"760": "Delubrum Reginae",
"761": "Delubrum Reginae (영웅)",
"777": "Paglth'an", "777": "Paglth'an",
"778": "Zadnor", "778": "Zadnor",
"779": "the Tower at Paradigm's Breach", "779": "the Tower at Paradigm's Breach",

View file

@ -1,11 +1,11 @@
# 日本語メッセージ # 日本語メッセージ
LANG=日本語 LANG=日本語
0=FFXIV dc 0=ドユコン
1=レディ 1=レディ
2=FFXIV プラグインが見つからないんです! 2=FFXIV プラグインが見つからないんです!
3=FFXIV プラグインを見つかりました! 3=FFXIV プラグインを見つかりました!
4=FFXIV ドユーティー・コンテンツが起動しました! 4=FFXIV ドユーティー・コンテンツ: {0}
5=ACT 情報: {0} ({1}) 5=ACT 情報: {0} ({1})
6=FFXIV プラグイン情報: {0} ({1}) 6=FFXIV プラグイン情報: {0} ({1})
7=データが壊れました: {0} 7=データが壊れました: {0}
@ -25,7 +25,7 @@ LANG=日本語
26=基本 26=基本
27=なし 27=なし
28=パケット・データが見つからないんです! {0} 28=パケット・データが見つからないんです! {0}
29=パケット情報: {0} "{1}" 29=パケット情報: {0} "{1}" ({2})
30=Webサービスにエラーが発生しました。 30=Webサービスにエラーが発生しました。
31=コンテンツ・データのアップデートが失敗しました。 31=コンテンツ・データのアップデートが失敗しました。
32=パケット・データのアップデートが失敗しまし。 32=パケット・データのアップデートが失敗しまし。
@ -44,6 +44,10 @@ LANG=日本語
203=データ・アップデート 203=データ・アップデート
204=ロカール・データのみ使う 204=ロカール・データのみ使う
205=ネットでチェック&アップデートする 205=ネットでチェック&アップデートする
206=アップデート!
207=新たなアップデートがあります! {0} → {1}
208=プラグインのウェブサイトでダウンロードしてください
209=https://github.com/kshman/DutyContent/releases/latest
300=コンテンツ 300=コンテンツ
301=コンテンツ 301=コンテンツ

View file

@ -1,11 +1,11 @@
# 한국말 메시지, 한국어 서비스(액토즈) # 한국말 메시지, 한국어 서비스(액토즈)
LANG=한국어(액토즈) LANG=한국어(액토즈)
0=FFXIV dc 0=듀티콘텐츠
1=준비됐습니다 1=준비됐습니다
2=FFXIV 플러그인이 없어요! 2=FFXIV 플러그인이 없어요!
3=FFXIV 플러그인을 찾았어요! 3=FFXIV 플러그인을 찾았어요!
4=FFXIV 듀티 콘텐츠 시작합니다! 4=FFXIV 듀티 콘텐츠: {0}
5=ACT 정보: {0} ({1}) 5=ACT 정보: {0} ({1})
6=FFXIV 플러그인 정보: {0} ({1}) 6=FFXIV 플러그인 정보: {0} ({1})
7=잘못된 데이터: {0} 7=잘못된 데이터: {0}
@ -25,7 +25,7 @@ LANG=한국어(액토즈)
26=기본 26=기본
27=없음 27=없음
28=패킷 파일이 없어요! {0} 28=패킷 파일이 없어요! {0}
29=패킷 정보: {0} "{1}" 29=패킷 정보: {0} "{1}" ({2})
30=웹 요청중 에러 발생 30=웹 요청중 에러 발생
31=임무 데이터 업데이트중 에러 발생 31=임무 데이터 업데이트중 에러 발생
32=패킷 데이터 업데이트중 에러 발생 32=패킷 데이터 업데이트중 에러 발생
@ -44,6 +44,10 @@ LANG=한국어(액토즈)
203=데이터 업데이트 203=데이터 업데이트
204=로컬 데이터만 사용합니다 204=로컬 데이터만 사용합니다
205=인터넷으로 새 데이터를 확인하고 받습니다 205=인터넷으로 새 데이터를 확인하고 받습니다
206=업데이트!!!
207=새 업데이트가 있습니다! {0} -> {1}
208=플러그인 웹사이트에서 받으세요.
209=https://github.com/kshman/DutyContent/releases/latest
300=임무 300=임무
301=콘텐츠 301=콘텐츠

View file

@ -1,11 +1,11 @@
# 한국말 메시지 # 한국말 메시지
LANG=한국어 LANG=한국어
0=FFXIV dc 0=듀티콘텐츠
1=준비됐습니다 1=준비됐습니다
2=FFXIV 플러그인이 없어요! 2=FFXIV 플러그인이 없어요!
3=FFXIV 플러그인을 찾았어요! 3=FFXIV 플러그인을 찾았어요!
4=FFXIV 듀티 콘텐츠 시작합니다! 4=FFXIV 듀티 콘텐츠: {0}
5=ACT 정보: {0} ({1}) 5=ACT 정보: {0} ({1})
6=FFXIV 플러그인 정보: {0} ({1}) 6=FFXIV 플러그인 정보: {0} ({1})
7=잘못된 데이터: {0} 7=잘못된 데이터: {0}
@ -25,7 +25,7 @@ LANG=한국어
26=기본 26=기본
27=없음 27=없음
28=패킷 파일이 없어요! {0} 28=패킷 파일이 없어요! {0}
29=패킷 정보: {0} "{1}" 29=패킷 정보: {0} "{1}" ({2})
30=웹 요청중 에러 발생 30=웹 요청중 에러 발생
31=임무 데이터 업데이트중 에러 발생 31=임무 데이터 업데이트중 에러 발생
32=패킷 데이터 업데이트중 에러 발생 32=패킷 데이터 업데이트중 에러 발생
@ -44,6 +44,10 @@ LANG=한국어
203=데이터 업데이트 203=데이터 업데이트
204=로컬 데이터만 사용합니다 204=로컬 데이터만 사용합니다
205=인터넷으로 새 데이터를 확인하고 받습니다 205=인터넷으로 새 데이터를 확인하고 받습니다
206=업데이트!!!
207=새 업데이트가 있습니다! {0} -> {1}
208=플러그인 웹사이트에서 받으세요.
209=https://github.com/kshman/DutyContent/releases/latest
300=듀티 300=듀티
301=콘텐츠 301=콘텐츠

View file

@ -14,6 +14,9 @@ namespace DutyContent
{ {
class DcConfig class DcConfig
{ {
public static int PluginTag => 10;
public static Version PluginVersion => System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
public static bool PluginEnable { get; set; } public static bool PluginEnable { get; set; }
public static string PluginPath { get; set; } public static string PluginPath { get; set; }
public static string DataPath { get; set; } public static string DataPath { get; set; }
@ -140,7 +143,7 @@ namespace DutyContent
// load. if file not exist, create new one with default value // load. if file not exist, create new one with default value
Packet.Load(filename); Packet.Load(filename);
MesgLog.I(29, Packet.Version, Packet.Description); MesgLog.I(29, Packet.Version, Packet.Description, filename);
return true; return true;
} }

View file

@ -138,6 +138,7 @@ namespace DutyContent
DcConfig.PluginEnable = false; DcConfig.PluginEnable = false;
Tab.UpdateNotifyForm.Self?.PluginDeinitialize();
Tab.PingForm.Self?.PluginDeinitialize(); Tab.PingForm.Self?.PluginDeinitialize();
Tab.DutyForm.Self?.PluginDeinitialize(); Tab.DutyForm.Self?.PluginDeinitialize();
Tab.ConfigForm.Self?.PluginDeinitialize(); Tab.ConfigForm.Self?.PluginDeinitialize();
@ -173,22 +174,17 @@ namespace DutyContent
MesgLog.SetTextBox(txtMesg); MesgLog.SetTextBox(txtMesg);
MesgLog.Initialize(Properties.Resources.DefaultMessage); MesgLog.Initialize(Properties.Resources.DefaultMessage);
MesgLog.C(Color.Aquamarine, 4); MesgLog.C(Color.Aquamarine, 4, DcConfig.PluginVersion.ToString());
DcConfig.LoadConfig(); DcConfig.LoadConfig();
DcConfig.ReadLanguage(true); DcConfig.ReadLanguage(true);
DcConfig.ReadPacket();
DcContent.ReadContent(); DcContent.ReadContent();
DcConfig.ReadPacket();
UpdateUiLocale(); UpdateUiLocale();
MesgLog.C(Color.Aquamarine, 4);
// //
Dock = DockStyle.Fill; Dock = DockStyle.Fill;
_act_label.Text = MesgLog.Text(1); // Duty ready
_act_tab.Text = MesgLog.Text(0); // FFXIV dc
_act_tab.Controls.Add(this); _act_tab.Controls.Add(this);
// //
@ -196,6 +192,34 @@ namespace DutyContent
Tab.DutyForm.Self?.PluginInitialize(); Tab.DutyForm.Self?.PluginInitialize();
Tab.PingForm.Self?.PluginInitialize(); Tab.PingForm.Self?.PluginInitialize();
//
if (DcConfig.DataRemoteUpdate)
{
var tag = Updater.CheckPluginUpdate(out string body);
if (tag > DcConfig.PluginTag)
{
Tab.UpdateNotifyForm frm = new Tab.UpdateNotifyForm(tag, body);
frm.PluginInitialize();
frm.UpdateUiLocale();
TabPage tp = new TabPage(MesgLog.Text(206));
try
{
// why? sometimes trouble
tp.Controls.Add(frm.Controls[0]);
}
catch (Exception ex)
{
MesgLog.Ex(ex);
}
tabMain.TabPages.Add(tp);
tabMain.SelectedTab = tp;
MesgLog.C(Color.Aquamarine, 207, DcConfig.PluginTag, tag);
}
}
// //
DcConfig.PluginEnable = true; DcConfig.PluginEnable = true;
@ -241,7 +265,7 @@ namespace DutyContent
} }
// //
public void RefreshSaveConfig(int interval=5000) public void RefreshSaveConfig(int interval = 5000)
{ {
_save_timer.Enabled = false; _save_timer.Enabled = false;
_save_timer.Interval = interval; _save_timer.Interval = interval;
@ -322,6 +346,9 @@ namespace DutyContent
// //
public void UpdateUiLocale() public void UpdateUiLocale()
{ {
_act_label.Text = MesgLog.Text(1); // Duty ready
_act_tab.Text = MesgLog.Text(0); // FFXIV dc
tabPageDuty.Text = MesgLog.Text(300); tabPageDuty.Text = MesgLog.Text(300);
Tab.DutyForm.Self?.UpdateUiLocale(); Tab.DutyForm.Self?.UpdateUiLocale();
@ -330,6 +357,8 @@ namespace DutyContent
tabPageConfig.Text = MesgLog.Text(200); tabPageConfig.Text = MesgLog.Text(200);
Tab.ConfigForm.Self?.UpdateUiLocale(); Tab.ConfigForm.Self?.UpdateUiLocale();
Tab.UpdateNotifyForm.Self?.UpdateUiLocale();
} }
} }
} }

View file

@ -101,6 +101,12 @@
<Compile Include="Tab\PingForm.Designer.cs"> <Compile Include="Tab\PingForm.Designer.cs">
<DependentUpon>PingForm.cs</DependentUpon> <DependentUpon>PingForm.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Tab\UpdateNotifyForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Tab\UpdateNotifyForm.Designer.cs">
<DependentUpon>UpdateNotifyForm.cs</DependentUpon>
</Compile>
<Compile Include="ThirdParty\Converter.cs" /> <Compile Include="ThirdParty\Converter.cs" />
<Compile Include="ThirdParty\LineDb.cs" /> <Compile Include="ThirdParty\LineDb.cs" />
<Compile Include="ThirdParty\NativeMethods.cs" /> <Compile Include="ThirdParty\NativeMethods.cs" />
@ -143,6 +149,9 @@
<EmbeddedResource Include="Tab\PingForm.resx"> <EmbeddedResource Include="Tab\PingForm.resx">
<DependentUpon>PingForm.cs</DependentUpon> <DependentUpon>PingForm.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="Tab\UpdateNotifyForm.resx">
<DependentUpon>UpdateNotifyForm.cs</DependentUpon>
</EmbeddedResource>
<None Include="Data\DcDuty-English.json" /> <None Include="Data\DcDuty-English.json" />
<None Include="Data\DcDuty-German.json" /> <None Include="Data\DcDuty-German.json" />
<None Include="Data\DcDuty-Japanese.json" /> <None Include="Data\DcDuty-Japanese.json" />

View file

@ -1,13 +1,13 @@
# Default English message # Default English message
LANG=English LANG=English
0=FFXIV dc 0=DutyCon
1=Duty ready 1=Duty ready
2=FFXIV plugin is missing! 2=FFXIV plugin is missing!
3=FFXIV plugin found! 3=FFXIV plugin found!
4=FFXIV Duty Content starting! 4=FFXIV Duty Content: {0}
5=ACT info: {0} ({1}) 5=ACT info: {0} ({1})
6=FFXIV plugin info {0} ({1}) 6=FFXIV plugin info: {0} ({1})
7=Invalid data: {0} 7=Invalid data: {0}
8=Parsing error 8=Parsing error
9=Unknown roulette: {0} 9=Unknown roulette: {0}
@ -25,7 +25,7 @@ LANG=English
26=Default 26=Default
27=None 27=None
28=Packet file not found! {0} 28=Packet file not found! {0}
29=Packet info: {0} "{1}" 29=Packet info: {0} "{1}" ({2})
30=Error requesting web service 30=Error requesting web service
31=Error while updating duty/FATE Data 31=Error while updating duty/FATE Data
32=Error while updating packet info 32=Error while updating packet info
@ -44,6 +44,10 @@ LANG=English
203=Data update 203=Data update
204=Use local data only 204=Use local data only
205=Check && update using Internet 205=Check && update using Internet
206=UPDATE!!!
207=New update found! {0} -> {1}
208=Visit DutyContent plugin repository for download.
209=https://github.com/kshman/DutyContent/releases/latest
300=Duty 300=Duty
301=Contents 301=Contents

View file

@ -10,6 +10,7 @@ using System.Net.Http;
using System.Text; using System.Text;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Collections.Specialized;
namespace DutyContent.Tab namespace DutyContent.Tab
{ {
@ -22,10 +23,12 @@ namespace DutyContent.Tab
private bool _is_lock_fate; private bool _is_lock_fate;
private bool _is_packet_finder; private bool _is_packet_finder;
private DcContent.SaveTheQueenType _stq_type = DcContent.SaveTheQueenType.No; private DcContent.SaveTheQueenType _stq_type = DcContent.SaveTheQueenType.No;
private DcConfig.PacketConfig _new_packet; private DcConfig.PacketConfig _new_packet;
private List<string> _packet_names = new List<string>();
private Dictionary<string, string> _packet_list = new Dictionary<string, string>();
//private OrderedDictionary _packet_list = new OrderedDictionary();
//
private Overlay.DutyOvForm _overlay; private Overlay.DutyOvForm _overlay;
public DutyForm() public DutyForm()
@ -48,29 +51,8 @@ namespace DutyContent.Tab
lblCurrentDataSet.Text = DcContent.DisplayLanguage; lblCurrentDataSet.Text = DcContent.DisplayLanguage;
// //
var lang = MakeDutyLangList(); RefreshDatasetList();
RefreshPacketList();
foreach (var i in lang)
{
var n = cboDataset.Items.Add(i);
if (i.Equals(DcConfig.Duty.Language))
cboDataset.SelectedIndex = n;
}
//
_packet_names.Clear();
var pks = MakePacketList();
for (var i = 0; i < pks.name.Count; i++)
{
var n = cboPacketset.Items.Add(pks.desc[i]);
if (pks.name[i].Equals(DcConfig.Duty.PacketSet))
cboPacketset.SelectedIndex = n;
_packet_names.Add(pks.name[i]);
}
// //
var font = new Font(DcConfig.Duty.LogFontFamily, DcConfig.Duty.LogFontSize, FontStyle.Regular, GraphicsUnit.Point); var font = new Font(DcConfig.Duty.LogFontFamily, DcConfig.Duty.LogFontSize, FontStyle.Regular, GraphicsUnit.Point);
@ -86,7 +68,7 @@ namespace DutyContent.Tab
chkOverlayClickThru.Checked = DcConfig.Duty.OverlayClickThru; chkOverlayClickThru.Checked = DcConfig.Duty.OverlayClickThru;
// //
_overlay.SetText(MesgLog.Text(99, System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString())); _overlay.SetText(MesgLog.Text(99, DcConfig.PluginVersion.ToString()));
_overlay.Location = DcConfig.Duty.OverlayLocation; _overlay.Location = DcConfig.Duty.OverlayLocation;
if (DcConfig.Duty.EnableOverlay) if (DcConfig.Duty.EnableOverlay)
@ -134,7 +116,10 @@ namespace DutyContent.Tab
// //
if (cboPacketset.SelectedIndex >= 0) if (cboPacketset.SelectedIndex >= 0)
RemotePacketUpdate(_packet_names[cboPacketset.SelectedIndex]); {
var p = _packet_list.ElementAt(cboPacketset.SelectedIndex);
RemotePacketUpdate(p.Key);
}
} }
public void PluginDeinitialize() public void PluginDeinitialize()
@ -148,45 +133,6 @@ namespace DutyContent.Tab
DcControl.Self.RefreshSaveConfig(interval); DcControl.Self.RefreshSaveConfig(interval);
} }
public static List<string> MakeDutyLangList()
{
List<string> lst = new List<string>();
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);
lst.Add(s);
}
return lst;
}
public static (List<string> name, List<string> desc) MakePacketList()
{
List<string> l = new List<string>();
List<string> d = new List<string>();
DirectoryInfo di = new DirectoryInfo(DcConfig.DataPath);
foreach (var fi in di.GetFiles("DcPacket-*.config"))
{
var s = fi.Name.Substring(9, fi.Name.Length - 9 - 7);
l.Add(s);
if (!File.Exists(fi.FullName))
d.Add(s);
else
{
var db = new ThirdParty.LineDb(fi.FullName, Encoding.UTF8, false);
d.Add(db.Get("Description", s));
}
}
return (l, d);
}
public void RefreshLocale() public void RefreshLocale()
{ {
@ -269,7 +215,7 @@ namespace DutyContent.Tab
if (DcConfig.Duty.Fates[DcConfig.Duty.ActiveFate].Selected.Contains(fcode)) if (DcConfig.Duty.Fates[DcConfig.Duty.ActiveFate].Selected.Contains(fcode))
{ {
MesgLog.L("{0} - {1}", DcConfig.Duty.ActiveFate, fcode); //MesgLog.L("{0} - {1}", DcConfig.Duty.ActiveFate, fcode);
PlayEffectSoundFate(); PlayEffectSoundFate();
NotifyFate(fate); NotifyFate(fate);
_overlay.PlayFate(fate); _overlay.PlayFate(fate);
@ -597,19 +543,20 @@ namespace DutyContent.Tab
if (!DcConfig.PluginEnable) if (!DcConfig.PluginEnable)
return; return;
if (cboPacketset.SelectedIndex >= _packet_names.Count) if (cboPacketset.SelectedIndex >= _packet_list.Count)
return; return;
var l = _packet_names[cboPacketset.SelectedIndex]; var p = _packet_list.ElementAt(cboPacketset.SelectedIndex);
var n = p.Key;
if (!string.IsNullOrWhiteSpace(l) && !l.Equals(DcConfig.Duty.PacketSet) && DcConfig.ReadPacket(l)) if (!string.IsNullOrWhiteSpace(n) && !n.Equals(DcConfig.Duty.PacketSet) && DcConfig.ReadPacket(n))
{ {
SaveConfig(); SaveConfig();
if (!l.Equals(DcConfig.PacketConfig.DefaultSetNameCustom)) if (!n.Equals(DcConfig.PacketConfig.DefaultSetNameCustom))
{ {
// check update and save // check update and save
RemotePacketUpdate(l); RemotePacketUpdate(n);
} }
} }
} }
@ -1449,9 +1396,69 @@ namespace DutyContent.Tab
MesgLog.I(33, pk.Version, pk.Description); MesgLog.I(33, pk.Version, pk.Description);
cboDataset.SelectedItem = 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;
}
}
} }
} }

121
Tab/UpdateNotifyForm.Designer.cs generated Normal file
View file

@ -0,0 +1,121 @@

namespace DutyContent.Tab
{
partial class UpdateNotifyForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.lblTitle = new System.Windows.Forms.Label();
this.lblMesg = new System.Windows.Forms.Label();
this.lblLink = new System.Windows.Forms.LinkLabel();
this.txtBody = new System.Windows.Forms.TextBox();
this.panel1 = new System.Windows.Forms.Panel();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// lblTitle
//
this.lblTitle.AutoSize = true;
this.lblTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 20.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblTitle.Location = new System.Drawing.Point(46, 0);
this.lblTitle.Name = "lblTitle";
this.lblTitle.Size = new System.Drawing.Size(62, 31);
this.lblTitle.TabIndex = 0;
this.lblTitle.Text = "207";
//
// lblMesg
//
this.lblMesg.AutoSize = true;
this.lblMesg.Location = new System.Drawing.Point(3, 50);
this.lblMesg.Name = "lblMesg";
this.lblMesg.Size = new System.Drawing.Size(25, 13);
this.lblMesg.TabIndex = 1;
this.lblMesg.Text = "208";
//
// lblLink
//
this.lblLink.AutoSize = true;
this.lblLink.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblLink.Location = new System.Drawing.Point(3, 87);
this.lblLink.Name = "lblLink";
this.lblLink.Size = new System.Drawing.Size(32, 18);
this.lblLink.TabIndex = 2;
this.lblLink.TabStop = true;
this.lblLink.Text = "209";
this.lblLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LblLink_LinkClicked);
//
// txtBody
//
this.txtBody.BackColor = System.Drawing.Color.OldLace;
this.txtBody.Location = new System.Drawing.Point(16, 108);
this.txtBody.Multiline = true;
this.txtBody.Name = "txtBody";
this.txtBody.ReadOnly = true;
this.txtBody.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.txtBody.Size = new System.Drawing.Size(464, 163);
this.txtBody.TabIndex = 3;
//
// panel1
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel1.AutoScroll = true;
this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panel1.Controls.Add(this.lblTitle);
this.panel1.Controls.Add(this.txtBody);
this.panel1.Controls.Add(this.lblMesg);
this.panel1.Controls.Add(this.lblLink);
this.panel1.Location = new System.Drawing.Point(12, 12);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(776, 426);
this.panel1.TabIndex = 4;
//
// UpdateNotifyForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoScroll = true;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.panel1);
this.Name = "UpdateNotifyForm";
this.Text = "Update";
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label lblTitle;
private System.Windows.Forms.Label lblMesg;
private System.Windows.Forms.LinkLabel lblLink;
private System.Windows.Forms.TextBox txtBody;
private System.Windows.Forms.Panel panel1;
}
}

59
Tab/UpdateNotifyForm.cs Normal file
View file

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DutyContent.Interface;
namespace DutyContent.Tab
{
public partial class UpdateNotifyForm : Form, Interface.ISuppLocale, Interface.ISuppActPlugin
{
private static UpdateNotifyForm _self;
public static UpdateNotifyForm Self => _self;
private int _newtag;
public UpdateNotifyForm(int newtag, string body)
{
_self = this;
InitializeComponent();
_newtag = newtag;
txtBody.Text = body;
}
public void PluginInitialize()
{
}
public void PluginDeinitialize()
{
}
public void RefreshLocale()
{
}
public void UpdateUiLocale()
{
lblTitle.Text = MesgLog.Text(207, DcConfig.PluginTag, _newtag);
lblMesg.Text = MesgLog.Text(208);
lblLink.Text = MesgLog.Text(209);
}
private void LblLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
Process.Start(lblLink.Text);
}
}
}

120
Tab/UpdateNotifyForm.resx Normal file
View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

59
ThirdParty/WebApi.cs vendored
View file

@ -6,37 +6,38 @@ using System.Text;
namespace DutyContent namespace DutyContent
{ {
internal static class WebApi internal static class WebApi
{ {
internal static string Request(string urlfmt, params object[] args) internal static string Request(string urlfmt, params object[] args)
{ {
try var url = string.Format(urlfmt, args);
{
var url = string.Format(urlfmt, args);
ServicePointManager.Expect100Continue = true; try
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; {
ServicePointManager.DefaultConnectionLimit = 9999; ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
ServicePointManager.DefaultConnectionLimit = 9999;
var request = (HttpWebRequest)WebRequest.Create(url); var request = (HttpWebRequest)WebRequest.Create(url);
request.UserAgent = "DFA"; request.UserAgent = "DFA";
request.Timeout = 10000; request.Timeout = 10000;
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore); request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
using (var response = (HttpWebResponse)request.GetResponse()) using (var response = (HttpWebResponse)request.GetResponse())
{ {
var encoding = Encoding.GetEncoding(response.CharacterSet); var encoding = Encoding.GetEncoding(response.CharacterSet);
using (var responseStream = response.GetResponseStream()) using (var responseStream = response.GetResponseStream())
using (var reader = new StreamReader(responseStream, encoding)) using (var reader = new StreamReader(responseStream, encoding))
return reader.ReadToEnd(); return reader.ReadToEnd();
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
MesgLog.Ex(ex, 30); MesgLog.Ex(ex, 30);
} MesgLog.L("URL: {0}", url);
}
return null; return null;
} }
} }
} }

View file

@ -4,38 +4,75 @@ using Newtonsoft.Json;
namespace DutyContent namespace DutyContent
{ {
internal class Updater internal class Updater
{ {
internal static void CheckNewVersion() // https://raw.githubusercontent.com/kshman/DutyContent/main/Data/####-####.####
{ // https://api.github.com/repos/kshman/DutyContent/releases/latest
Task.Factory.StartNew(() =>
{
try
{
var json = WebApi.Request($"https://raw.githubusercontent.com/kshman/DutyContent/main/Data/DcDuty-{DcContent.Language}.json");
DcContent.Fill(json);
}
catch (Exception ex)
{
MesgLog.Ex(ex, 31);
}
});
}
public static string CheckNewPacket(string name) private const string UrlContent = "https://raw.githubusercontent.com/kshman/DutyContent";
private const string UrlApiRepo = "https://api.github.com/repos/kshman/DutyContent";
private const string PathData = "main/Data";
private const string PfxDuty = "DcDuty";
private const string PfxPacket = "DcPacket";
internal static void CheckNewVersion()
{ {
try Task.Factory.StartNew(() =>
{ {
var ret = WebApi.Request($"https://raw.githubusercontent.com/kshman/DutyContent/main/Data/DcPacket-{name}.config"); try
{
var url = $"{UrlContent}/{PathData}/{PfxDuty}-{DcContent.Language}.json";
var json = WebApi.Request(url);
DcContent.Fill(json);
}
catch (Exception ex)
{
MesgLog.Ex(ex, 31);
}
});
}
return ret; public static string CheckNewPacket(string name)
} {
catch (Exception ex) try
{ {
MesgLog.Ex(ex, 32); var url = $"{UrlContent}/{PathData}/{PfxPacket}-{name}.config";
var ret = WebApi.Request(url);
return null; return ret;
}
catch (Exception ex)
{
MesgLog.Ex(ex, 32);
return null;
} }
} }
}
public static int CheckPluginUpdate(out string body)
{
body = string.Empty;
var url = $"{UrlApiRepo}/releases/latest";
var req = WebApi.Request(url);
if (!string.IsNullOrEmpty(req))
{
try
{
var js = JsonConvert.DeserializeObject<dynamic>(req);
var tag = js.tag_name.ToObject<string>();
body = js.body.ToObject<string>();
return ThirdParty.Converter.ToInt(tag);
}
catch (Exception /*ex*/)
{
}
}
return 0;
}
}
} }