Implement import from GOOD dump (#86)

* Implement import from GOOD dump

* Optimized implementation

* Add available urls

* Add prompt

Co-authored-by: Leo <chun.huang@student.manchester.ac.uk>
Co-authored-by: 筱傑 <jie65535@qq.com>
This commit is contained in:
gotoAndDie 2022-07-23 10:18:51 +08:00 committed by GitHub
parent 9eba1d6368
commit 2cb9f08caa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 6281 additions and 5378 deletions

View File

@ -35,6 +35,7 @@ namespace GrasscutterTools.Forms
this.GrpCommand = new System.Windows.Forms.GroupBox(); this.GrpCommand = new System.Windows.Forms.GroupBox();
this.BtnInvokeOpenCommand = new System.Windows.Forms.Button(); this.BtnInvokeOpenCommand = new System.Windows.Forms.Button();
this.TPRemoteCall = new System.Windows.Forms.TabPage(); this.TPRemoteCall = new System.Windows.Forms.TabPage();
this.ButtonOpenGOODImport = new System.Windows.Forms.Button();
this.LblHostTip = new System.Windows.Forms.Label(); this.LblHostTip = new System.Windows.Forms.Label();
this.GrpServerStatus = new System.Windows.Forms.GroupBox(); this.GrpServerStatus = new System.Windows.Forms.GroupBox();
this.LnkOpenCommandLabel = new System.Windows.Forms.LinkLabel(); this.LnkOpenCommandLabel = new System.Windows.Forms.LinkLabel();
@ -70,7 +71,6 @@ namespace GrasscutterTools.Forms
this.DTPBanEndTime = new System.Windows.Forms.DateTimePicker(); this.DTPBanEndTime = new System.Windows.Forms.DateTimePicker();
this.BtnUnban = new System.Windows.Forms.Button(); this.BtnUnban = new System.Windows.Forms.Button();
this.BtnBan = new System.Windows.Forms.Button(); this.BtnBan = new System.Windows.Forms.Button();
this.TxtBanReason = new GrasscutterTools.Controls.TextBoxXP();
this.NUDBanUID = new System.Windows.Forms.NumericUpDown(); this.NUDBanUID = new System.Windows.Forms.NumericUpDown();
this.LblBanUID = new System.Windows.Forms.Label(); this.LblBanUID = new System.Windows.Forms.Label();
this.GrpAccount = new System.Windows.Forms.GroupBox(); this.GrpAccount = new System.Windows.Forms.GroupBox();
@ -221,6 +221,7 @@ namespace GrasscutterTools.Forms
this.ChkIncludeUID = new System.Windows.Forms.CheckBox(); this.ChkIncludeUID = new System.Windows.Forms.CheckBox();
this.LblDefaultUid = new System.Windows.Forms.Label(); this.LblDefaultUid = new System.Windows.Forms.Label();
this.TCMain = new System.Windows.Forms.TabControl(); this.TCMain = new System.Windows.Forms.TabControl();
this.TxtBanReason = new GrasscutterTools.Controls.TextBoxXP();
this.GrpCommand.SuspendLayout(); this.GrpCommand.SuspendLayout();
this.TPRemoteCall.SuspendLayout(); this.TPRemoteCall.SuspendLayout();
this.GrpServerStatus.SuspendLayout(); this.GrpServerStatus.SuspendLayout();
@ -317,16 +318,24 @@ namespace GrasscutterTools.Forms
// //
// TPRemoteCall // TPRemoteCall
// //
resources.ApplyResources(this.TPRemoteCall, "TPRemoteCall"); this.TPRemoteCall.Controls.Add(this.ButtonOpenGOODImport);
this.TPRemoteCall.Controls.Add(this.LblHostTip); this.TPRemoteCall.Controls.Add(this.LblHostTip);
this.TPRemoteCall.Controls.Add(this.GrpServerStatus); this.TPRemoteCall.Controls.Add(this.GrpServerStatus);
this.TPRemoteCall.Controls.Add(this.GrpRemoteCommand); this.TPRemoteCall.Controls.Add(this.GrpRemoteCommand);
this.TPRemoteCall.Controls.Add(this.TxtHost); this.TPRemoteCall.Controls.Add(this.TxtHost);
this.TPRemoteCall.Controls.Add(this.BtnQueryServerStatus); this.TPRemoteCall.Controls.Add(this.BtnQueryServerStatus);
this.TPRemoteCall.Controls.Add(this.LblHost); this.TPRemoteCall.Controls.Add(this.LblHost);
resources.ApplyResources(this.TPRemoteCall, "TPRemoteCall");
this.TPRemoteCall.Name = "TPRemoteCall"; this.TPRemoteCall.Name = "TPRemoteCall";
this.TPRemoteCall.UseVisualStyleBackColor = true; this.TPRemoteCall.UseVisualStyleBackColor = true;
// //
// ButtonOpenGOODImport
//
resources.ApplyResources(this.ButtonOpenGOODImport, "ButtonOpenGOODImport");
this.ButtonOpenGOODImport.Name = "ButtonOpenGOODImport";
this.ButtonOpenGOODImport.UseVisualStyleBackColor = true;
this.ButtonOpenGOODImport.Click += new System.EventHandler(this.ButtonOpenGOODImport_Click);
//
// LblHostTip // LblHostTip
// //
resources.ApplyResources(this.LblHostTip, "LblHostTip"); resources.ApplyResources(this.LblHostTip, "LblHostTip");
@ -386,15 +395,14 @@ namespace GrasscutterTools.Forms
// //
// TPOpenCommandCheck // TPOpenCommandCheck
// //
resources.ApplyResources(this.TPOpenCommandCheck, "TPOpenCommandCheck");
this.TPOpenCommandCheck.Controls.Add(this.TPPlayerCheck); this.TPOpenCommandCheck.Controls.Add(this.TPPlayerCheck);
this.TPOpenCommandCheck.Controls.Add(this.TPConsoleCheck); this.TPOpenCommandCheck.Controls.Add(this.TPConsoleCheck);
resources.ApplyResources(this.TPOpenCommandCheck, "TPOpenCommandCheck");
this.TPOpenCommandCheck.Name = "TPOpenCommandCheck"; this.TPOpenCommandCheck.Name = "TPOpenCommandCheck";
this.TPOpenCommandCheck.SelectedIndex = 0; this.TPOpenCommandCheck.SelectedIndex = 0;
// //
// TPPlayerCheck // TPPlayerCheck
// //
resources.ApplyResources(this.TPPlayerCheck, "TPPlayerCheck");
this.TPPlayerCheck.Controls.Add(this.LnkRCHelp); this.TPPlayerCheck.Controls.Add(this.LnkRCHelp);
this.TPPlayerCheck.Controls.Add(this.NUDRemotePlayerId); this.TPPlayerCheck.Controls.Add(this.NUDRemotePlayerId);
this.TPPlayerCheck.Controls.Add(this.BtnConnectOpenCommand); this.TPPlayerCheck.Controls.Add(this.BtnConnectOpenCommand);
@ -402,6 +410,7 @@ namespace GrasscutterTools.Forms
this.TPPlayerCheck.Controls.Add(this.BtnSendVerificationCode); this.TPPlayerCheck.Controls.Add(this.BtnSendVerificationCode);
this.TPPlayerCheck.Controls.Add(this.NUDVerificationCode); this.TPPlayerCheck.Controls.Add(this.NUDVerificationCode);
this.TPPlayerCheck.Controls.Add(this.LblRemotePlayerId); this.TPPlayerCheck.Controls.Add(this.LblRemotePlayerId);
resources.ApplyResources(this.TPPlayerCheck, "TPPlayerCheck");
this.TPPlayerCheck.Name = "TPPlayerCheck"; this.TPPlayerCheck.Name = "TPPlayerCheck";
this.TPPlayerCheck.UseVisualStyleBackColor = true; this.TPPlayerCheck.UseVisualStyleBackColor = true;
// //
@ -473,11 +482,11 @@ namespace GrasscutterTools.Forms
// //
// TPConsoleCheck // TPConsoleCheck
// //
resources.ApplyResources(this.TPConsoleCheck, "TPConsoleCheck");
this.TPConsoleCheck.Controls.Add(this.BtnConsoleConnect); this.TPConsoleCheck.Controls.Add(this.BtnConsoleConnect);
this.TPConsoleCheck.Controls.Add(this.TxtToken); this.TPConsoleCheck.Controls.Add(this.TxtToken);
this.TPConsoleCheck.Controls.Add(this.LblToken); this.TPConsoleCheck.Controls.Add(this.LblToken);
this.TPConsoleCheck.Controls.Add(this.LblConsoleTip); this.TPConsoleCheck.Controls.Add(this.LblConsoleTip);
resources.ApplyResources(this.TPConsoleCheck, "TPConsoleCheck");
this.TPConsoleCheck.Name = "TPConsoleCheck"; this.TPConsoleCheck.Name = "TPConsoleCheck";
this.TPConsoleCheck.UseVisualStyleBackColor = true; this.TPConsoleCheck.UseVisualStyleBackColor = true;
// //
@ -522,10 +531,10 @@ namespace GrasscutterTools.Forms
// //
// TPAbout // TPAbout
// //
resources.ApplyResources(this.TPAbout, "TPAbout");
this.TPAbout.Controls.Add(this.GrasscutterToolsSupport); this.TPAbout.Controls.Add(this.GrasscutterToolsSupport);
this.TPAbout.Controls.Add(this.LnkGithub); this.TPAbout.Controls.Add(this.LnkGithub);
this.TPAbout.Controls.Add(this.LblSupportDescription); this.TPAbout.Controls.Add(this.LblSupportDescription);
resources.ApplyResources(this.TPAbout, "TPAbout");
this.TPAbout.Name = "TPAbout"; this.TPAbout.Name = "TPAbout";
this.TPAbout.UseVisualStyleBackColor = true; this.TPAbout.UseVisualStyleBackColor = true;
// //
@ -550,10 +559,10 @@ namespace GrasscutterTools.Forms
// //
// TPManage // TPManage
// //
resources.ApplyResources(this.TPManage, "TPManage");
this.TPManage.Controls.Add(this.GrpBanPlayer); this.TPManage.Controls.Add(this.GrpBanPlayer);
this.TPManage.Controls.Add(this.GrpAccount); this.TPManage.Controls.Add(this.GrpAccount);
this.TPManage.Controls.Add(this.GrpPermission); this.TPManage.Controls.Add(this.GrpPermission);
resources.ApplyResources(this.TPManage, "TPManage");
this.TPManage.Name = "TPManage"; this.TPManage.Name = "TPManage";
this.TPManage.UseVisualStyleBackColor = true; this.TPManage.UseVisualStyleBackColor = true;
// //
@ -571,8 +580,8 @@ namespace GrasscutterTools.Forms
// //
// DTPBanEndTime // DTPBanEndTime
// //
resources.ApplyResources(this.DTPBanEndTime, "DTPBanEndTime");
this.DTPBanEndTime.Format = System.Windows.Forms.DateTimePickerFormat.Short; this.DTPBanEndTime.Format = System.Windows.Forms.DateTimePickerFormat.Short;
resources.ApplyResources(this.DTPBanEndTime, "DTPBanEndTime");
this.DTPBanEndTime.MaxDate = new System.DateTime(2034, 12, 31, 0, 0, 0, 0); this.DTPBanEndTime.MaxDate = new System.DateTime(2034, 12, 31, 0, 0, 0, 0);
this.DTPBanEndTime.MinDate = new System.DateTime(2022, 6, 28, 0, 0, 0, 0); this.DTPBanEndTime.MinDate = new System.DateTime(2022, 6, 28, 0, 0, 0, 0);
this.DTPBanEndTime.Name = "DTPBanEndTime"; this.DTPBanEndTime.Name = "DTPBanEndTime";
@ -592,14 +601,6 @@ namespace GrasscutterTools.Forms
this.BtnBan.UseVisualStyleBackColor = true; this.BtnBan.UseVisualStyleBackColor = true;
this.BtnBan.Click += new System.EventHandler(this.BtnBan_Click); this.BtnBan.Click += new System.EventHandler(this.BtnBan_Click);
// //
// TxtBanReason
//
resources.ApplyResources(this.TxtBanReason, "TxtBanReason");
this.TxtBanReason.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.TxtBanReason.Maximum = 0F;
this.TxtBanReason.Minimum = 0F;
this.TxtBanReason.Name = "TxtBanReason";
//
// NUDBanUID // NUDBanUID
// //
resources.ApplyResources(this.NUDBanUID, "NUDBanUID"); resources.ApplyResources(this.NUDBanUID, "NUDBanUID");
@ -693,10 +694,10 @@ namespace GrasscutterTools.Forms
// //
// CmbPerm // CmbPerm
// //
resources.ApplyResources(this.CmbPerm, "CmbPerm");
this.CmbPerm.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend; this.CmbPerm.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
this.CmbPerm.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems; this.CmbPerm.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
this.CmbPerm.FormattingEnabled = true; this.CmbPerm.FormattingEnabled = true;
resources.ApplyResources(this.CmbPerm, "CmbPerm");
this.CmbPerm.Name = "CmbPerm"; this.CmbPerm.Name = "CmbPerm";
// //
// NUDPermUID // NUDPermUID
@ -742,7 +743,6 @@ namespace GrasscutterTools.Forms
// //
// TPScene // TPScene
// //
resources.ApplyResources(this.TPScene, "TPScene");
this.TPScene.Controls.Add(this.TxtSceneFilter); this.TPScene.Controls.Add(this.TxtSceneFilter);
this.TPScene.Controls.Add(this.ChkIncludeSceneId); this.TPScene.Controls.Add(this.ChkIncludeSceneId);
this.TPScene.Controls.Add(this.LblTp); this.TPScene.Controls.Add(this.LblTp);
@ -757,6 +757,7 @@ namespace GrasscutterTools.Forms
this.TPScene.Controls.Add(this.LblClimateType); this.TPScene.Controls.Add(this.LblClimateType);
this.TPScene.Controls.Add(this.LblSceneDescription); this.TPScene.Controls.Add(this.LblSceneDescription);
this.TPScene.Controls.Add(this.ListScenes); this.TPScene.Controls.Add(this.ListScenes);
resources.ApplyResources(this.TPScene, "TPScene");
this.TPScene.Name = "TPScene"; this.TPScene.Name = "TPScene";
this.TPScene.UseVisualStyleBackColor = true; this.TPScene.UseVisualStyleBackColor = true;
// //
@ -891,7 +892,6 @@ namespace GrasscutterTools.Forms
// //
// TPItem // TPItem
// //
resources.ApplyResources(this.TPItem, "TPItem");
this.TPItem.Controls.Add(this.LblClearGiveItemLogs); this.TPItem.Controls.Add(this.LblClearGiveItemLogs);
this.TPItem.Controls.Add(this.BtnSaveGiveItemLog); this.TPItem.Controls.Add(this.BtnSaveGiveItemLog);
this.TPItem.Controls.Add(this.BtnRemoveGiveItemLog); this.TPItem.Controls.Add(this.BtnRemoveGiveItemLog);
@ -904,6 +904,7 @@ namespace GrasscutterTools.Forms
this.TPItem.Controls.Add(this.NUDGameItemAmout); this.TPItem.Controls.Add(this.NUDGameItemAmout);
this.TPItem.Controls.Add(this.NUDGameItemLevel); this.TPItem.Controls.Add(this.NUDGameItemLevel);
this.TPItem.Controls.Add(this.LblGiveCommandDescription); this.TPItem.Controls.Add(this.LblGiveCommandDescription);
resources.ApplyResources(this.TPItem, "TPItem");
this.TPItem.Name = "TPItem"; this.TPItem.Name = "TPItem";
this.TPItem.UseVisualStyleBackColor = true; this.TPItem.UseVisualStyleBackColor = true;
// //
@ -1021,7 +1022,6 @@ namespace GrasscutterTools.Forms
// //
// TPWeapon // TPWeapon
// //
resources.ApplyResources(this.TPWeapon, "TPWeapon");
this.TPWeapon.Controls.Add(this.TxtWeaponFilter); this.TPWeapon.Controls.Add(this.TxtWeaponFilter);
this.TPWeapon.Controls.Add(this.LblWeaponDescription); this.TPWeapon.Controls.Add(this.LblWeaponDescription);
this.TPWeapon.Controls.Add(this.LblWeaponRefinement); this.TPWeapon.Controls.Add(this.LblWeaponRefinement);
@ -1031,6 +1031,7 @@ namespace GrasscutterTools.Forms
this.TPWeapon.Controls.Add(this.NUDWeaponAmout); this.TPWeapon.Controls.Add(this.NUDWeaponAmout);
this.TPWeapon.Controls.Add(this.NUDWeaponLevel); this.TPWeapon.Controls.Add(this.NUDWeaponLevel);
this.TPWeapon.Controls.Add(this.ListWeapons); this.TPWeapon.Controls.Add(this.ListWeapons);
resources.ApplyResources(this.TPWeapon, "TPWeapon");
this.TPWeapon.Name = "TPWeapon"; this.TPWeapon.Name = "TPWeapon";
this.TPWeapon.UseVisualStyleBackColor = true; this.TPWeapon.UseVisualStyleBackColor = true;
// //
@ -1127,12 +1128,12 @@ namespace GrasscutterTools.Forms
// //
// TPStats // TPStats
// //
resources.ApplyResources(this.TPStats, "TPStats");
this.TPStats.Controls.Add(this.LblResetStatsCommand); this.TPStats.Controls.Add(this.LblResetStatsCommand);
this.TPStats.Controls.Add(this.LblResetStatsTip); this.TPStats.Controls.Add(this.LblResetStatsTip);
this.TPStats.Controls.Add(this.GrpSetStats); this.TPStats.Controls.Add(this.GrpSetStats);
this.TPStats.Controls.Add(this.GrpTalentLevel); this.TPStats.Controls.Add(this.GrpTalentLevel);
this.TPStats.Controls.Add(this.LblStatsDescription); this.TPStats.Controls.Add(this.LblStatsDescription);
resources.ApplyResources(this.TPStats, "TPStats");
this.TPStats.Name = "TPStats"; this.TPStats.Name = "TPStats";
this.TPStats.UseVisualStyleBackColor = true; this.TPStats.UseVisualStyleBackColor = true;
// //
@ -1161,9 +1162,9 @@ namespace GrasscutterTools.Forms
// //
// LblStatTip // LblStatTip
// //
resources.ApplyResources(this.LblStatTip, "LblStatTip");
this.LblStatTip.AutoEllipsis = true; this.LblStatTip.AutoEllipsis = true;
this.LblStatTip.ForeColor = System.Drawing.SystemColors.GrayText; this.LblStatTip.ForeColor = System.Drawing.SystemColors.GrayText;
resources.ApplyResources(this.LblStatTip, "LblStatTip");
this.LblStatTip.Name = "LblStatTip"; this.LblStatTip.Name = "LblStatTip";
// //
// LblStatPercent // LblStatPercent
@ -1189,9 +1190,9 @@ namespace GrasscutterTools.Forms
// //
// CmbStat // CmbStat
// //
resources.ApplyResources(this.CmbStat, "CmbStat");
this.CmbStat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.CmbStat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.CmbStat.FormattingEnabled = true; this.CmbStat.FormattingEnabled = true;
resources.ApplyResources(this.CmbStat, "CmbStat");
this.CmbStat.Name = "CmbStat"; this.CmbStat.Name = "CmbStat";
this.CmbStat.SelectedIndexChanged += new System.EventHandler(this.SetStatsInputChanged); this.CmbStat.SelectedIndexChanged += new System.EventHandler(this.SetStatsInputChanged);
// //
@ -1251,7 +1252,6 @@ namespace GrasscutterTools.Forms
// //
// TPAvatar // TPAvatar
// //
resources.ApplyResources(this.TPAvatar, "TPAvatar");
this.TPAvatar.Controls.Add(this.BtnGiveAllChar); this.TPAvatar.Controls.Add(this.BtnGiveAllChar);
this.TPAvatar.Controls.Add(this.LblConstellationTip); this.TPAvatar.Controls.Add(this.LblConstellationTip);
this.TPAvatar.Controls.Add(this.LblAvatarConstellation); this.TPAvatar.Controls.Add(this.LblAvatarConstellation);
@ -1261,6 +1261,7 @@ namespace GrasscutterTools.Forms
this.TPAvatar.Controls.Add(this.LblAvatarLevel); this.TPAvatar.Controls.Add(this.LblAvatarLevel);
this.TPAvatar.Controls.Add(this.NUDAvatarLevel); this.TPAvatar.Controls.Add(this.NUDAvatarLevel);
this.TPAvatar.Controls.Add(this.CmbAvatar); this.TPAvatar.Controls.Add(this.CmbAvatar);
resources.ApplyResources(this.TPAvatar, "TPAvatar");
this.TPAvatar.Name = "TPAvatar"; this.TPAvatar.Name = "TPAvatar";
this.TPAvatar.UseVisualStyleBackColor = true; this.TPAvatar.UseVisualStyleBackColor = true;
// //
@ -1346,7 +1347,6 @@ namespace GrasscutterTools.Forms
// //
// TPSpawn // TPSpawn
// //
resources.ApplyResources(this.TPSpawn, "TPSpawn");
this.TPSpawn.Controls.Add(this.LblClearSpawnLogs); this.TPSpawn.Controls.Add(this.LblClearSpawnLogs);
this.TPSpawn.Controls.Add(this.BtnSaveSpawnLog); this.TPSpawn.Controls.Add(this.BtnSaveSpawnLog);
this.TPSpawn.Controls.Add(this.BtnRemoveSpawnLog); this.TPSpawn.Controls.Add(this.BtnRemoveSpawnLog);
@ -1359,6 +1359,7 @@ namespace GrasscutterTools.Forms
this.TPSpawn.Controls.Add(this.NUDEntityLevel); this.TPSpawn.Controls.Add(this.NUDEntityLevel);
this.TPSpawn.Controls.Add(this.TxtEntityFilter); this.TPSpawn.Controls.Add(this.TxtEntityFilter);
this.TPSpawn.Controls.Add(this.ListEntity); this.TPSpawn.Controls.Add(this.ListEntity);
resources.ApplyResources(this.TPSpawn, "TPSpawn");
this.TPSpawn.Name = "TPSpawn"; this.TPSpawn.Name = "TPSpawn";
this.TPSpawn.UseVisualStyleBackColor = true; this.TPSpawn.UseVisualStyleBackColor = true;
// //
@ -1499,13 +1500,13 @@ namespace GrasscutterTools.Forms
// //
// TPQuest // TPQuest
// //
resources.ApplyResources(this.TPQuest, "TPQuest");
this.TPQuest.Controls.Add(this.GrpQuestFilters); this.TPQuest.Controls.Add(this.GrpQuestFilters);
this.TPQuest.Controls.Add(this.BtnFinishQuest); this.TPQuest.Controls.Add(this.BtnFinishQuest);
this.TPQuest.Controls.Add(this.BtnAddQuest); this.TPQuest.Controls.Add(this.BtnAddQuest);
this.TPQuest.Controls.Add(this.LblQuestDescription); this.TPQuest.Controls.Add(this.LblQuestDescription);
this.TPQuest.Controls.Add(this.TxtQuestFilter); this.TPQuest.Controls.Add(this.TxtQuestFilter);
this.TPQuest.Controls.Add(this.ListQuest); this.TPQuest.Controls.Add(this.ListQuest);
resources.ApplyResources(this.TPQuest, "TPQuest");
this.TPQuest.Name = "TPQuest"; this.TPQuest.Name = "TPQuest";
this.TPQuest.UseVisualStyleBackColor = true; this.TPQuest.UseVisualStyleBackColor = true;
// //
@ -1577,7 +1578,6 @@ namespace GrasscutterTools.Forms
// //
// TPArtifact // TPArtifact
// //
resources.ApplyResources(this.TPArtifact, "TPArtifact");
this.TPArtifact.Controls.Add(this.LblArtifactLevelTip); this.TPArtifact.Controls.Add(this.LblArtifactLevelTip);
this.TPArtifact.Controls.Add(this.BtnAddSubAttr); this.TPArtifact.Controls.Add(this.BtnAddSubAttr);
this.TPArtifact.Controls.Add(this.LblArtifactName); this.TPArtifact.Controls.Add(this.LblArtifactName);
@ -1597,6 +1597,7 @@ namespace GrasscutterTools.Forms
this.TPArtifact.Controls.Add(this.NUDArtifactLevel); this.TPArtifact.Controls.Add(this.NUDArtifactLevel);
this.TPArtifact.Controls.Add(this.LblArtifactStars); this.TPArtifact.Controls.Add(this.LblArtifactStars);
this.TPArtifact.Controls.Add(this.NUDArtifactStars); this.TPArtifact.Controls.Add(this.NUDArtifactStars);
resources.ApplyResources(this.TPArtifact, "TPArtifact");
this.TPArtifact.Name = "TPArtifact"; this.TPArtifact.Name = "TPArtifact";
this.TPArtifact.UseVisualStyleBackColor = true; this.TPArtifact.UseVisualStyleBackColor = true;
// //
@ -1762,7 +1763,6 @@ namespace GrasscutterTools.Forms
// //
// TPCustom // TPCustom
// //
resources.ApplyResources(this.TPCustom, "TPCustom");
this.TPCustom.Controls.Add(this.BtnExportCustomCommands); this.TPCustom.Controls.Add(this.BtnExportCustomCommands);
this.TPCustom.Controls.Add(this.BtnLoadCustomCommands); this.TPCustom.Controls.Add(this.BtnLoadCustomCommands);
this.TPCustom.Controls.Add(this.LblCustomName); this.TPCustom.Controls.Add(this.LblCustomName);
@ -1770,6 +1770,7 @@ namespace GrasscutterTools.Forms
this.TPCustom.Controls.Add(this.BtnRemoveCustomCommand); this.TPCustom.Controls.Add(this.BtnRemoveCustomCommand);
this.TPCustom.Controls.Add(this.BtnSaveCustomCommand); this.TPCustom.Controls.Add(this.BtnSaveCustomCommand);
this.TPCustom.Controls.Add(this.TxtCustomName); this.TPCustom.Controls.Add(this.TxtCustomName);
resources.ApplyResources(this.TPCustom, "TPCustom");
this.TPCustom.Name = "TPCustom"; this.TPCustom.Name = "TPCustom";
this.TPCustom.UseVisualStyleBackColor = true; this.TPCustom.UseVisualStyleBackColor = true;
// //
@ -1833,12 +1834,12 @@ namespace GrasscutterTools.Forms
// //
// TPHome // TPHome
// //
resources.ApplyResources(this.TPHome, "TPHome");
this.TPHome.Controls.Add(this.LblAbout); this.TPHome.Controls.Add(this.LblAbout);
this.TPHome.Controls.Add(this.BtnOpenTextMap); this.TPHome.Controls.Add(this.BtnOpenTextMap);
this.TPHome.Controls.Add(this.BtnOpenGachaBannerEditor); this.TPHome.Controls.Add(this.BtnOpenGachaBannerEditor);
this.TPHome.Controls.Add(this.GrasscutterToolsIcon); this.TPHome.Controls.Add(this.GrasscutterToolsIcon);
this.TPHome.Controls.Add(this.GrpSettings); this.TPHome.Controls.Add(this.GrpSettings);
resources.ApplyResources(this.TPHome, "TPHome");
this.TPHome.Name = "TPHome"; this.TPHome.Name = "TPHome";
this.TPHome.UseVisualStyleBackColor = true; this.TPHome.UseVisualStyleBackColor = true;
// //
@ -1897,9 +1898,9 @@ namespace GrasscutterTools.Forms
// //
// CmbLanguage // CmbLanguage
// //
resources.ApplyResources(this.CmbLanguage, "CmbLanguage");
this.CmbLanguage.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.CmbLanguage.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.CmbLanguage.FormattingEnabled = true; this.CmbLanguage.FormattingEnabled = true;
resources.ApplyResources(this.CmbLanguage, "CmbLanguage");
this.CmbLanguage.Name = "CmbLanguage"; this.CmbLanguage.Name = "CmbLanguage";
this.CmbLanguage.SelectedIndexChanged += new System.EventHandler(this.CmbLanguage_SelectedIndexChanged); this.CmbLanguage.SelectedIndexChanged += new System.EventHandler(this.CmbLanguage_SelectedIndexChanged);
// //
@ -1953,6 +1954,14 @@ namespace GrasscutterTools.Forms
this.TCMain.Name = "TCMain"; this.TCMain.Name = "TCMain";
this.TCMain.SelectedIndex = 0; this.TCMain.SelectedIndex = 0;
// //
// TxtBanReason
//
this.TxtBanReason.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
resources.ApplyResources(this.TxtBanReason, "TxtBanReason");
this.TxtBanReason.Maximum = 0F;
this.TxtBanReason.Minimum = 0F;
this.TxtBanReason.Name = "TxtBanReason";
//
// FormMain // FormMain
// //
resources.ApplyResources(this, "$this"); resources.ApplyResources(this, "$this");
@ -2244,5 +2253,6 @@ namespace GrasscutterTools.Forms
private System.Windows.Forms.Label LblConstellationTip; private System.Windows.Forms.Label LblConstellationTip;
private System.Windows.Forms.Button BtnGiveAllChar; private System.Windows.Forms.Button BtnGiveAllChar;
private System.Windows.Forms.Label LblHostTip; private System.Windows.Forms.Label LblHostTip;
private System.Windows.Forms.Button ButtonOpenGOODImport;
} }
} }

View File

@ -21,6 +21,7 @@ using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Security;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -28,8 +29,11 @@ using System.Windows.Forms;
using GrasscutterTools.DispatchServer; using GrasscutterTools.DispatchServer;
using GrasscutterTools.Game; using GrasscutterTools.Game;
using GrasscutterTools.GOOD;
using GrasscutterTools.OpenCommand; using GrasscutterTools.OpenCommand;
using GrasscutterTools.Properties; using GrasscutterTools.Properties;
using GrasscutterTools.Utils;
using Newtonsoft.Json;
namespace GrasscutterTools.Forms namespace GrasscutterTools.Forms
{ {
@ -202,6 +206,125 @@ namespace GrasscutterTools.Forms
TextMapBrowser.TopMost = false; TextMapBrowser.TopMost = false;
} }
} }
async private void ButtonOpenGOODImport_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog
{
Filter = "GOOD file (*.GOOD;*.json)|*.GOOD;*.json|All files (*.*)|*.*",
};
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
if (DialogResult.Yes != MessageBox.Show(Resources.GOODImportText + openFileDialog1.FileName + "?",
Resources.GOODImportTitle, MessageBoxButtons.YesNo))
return;
try
{
GOOD.GOOD good = JsonConvert.DeserializeObject<GOOD.GOOD>(File.ReadAllText(openFileDialog1.FileName));
var commands_list = new List<string>();
var missingItems = new List<string>();
if (good.Characters != null)
{
foreach (var character in good.Characters)
{
if (character.Name != "Traveler")
{
if (GOODData.Avatars.TryGetValue(character.Name, out var character_id))
commands_list.Add("/give " + character_id + " lv" + character.Level + "c" + character.Constellation);
else
missingItems.Add(character.Name);
// TODO: Implement command to set talent level when giving character in Grasscutter
}
}
}
if (good.Weapons != null)
{
foreach (var weapon in good.Weapons)
{
if (GOODData.Weapons.TryGetValue(weapon.Name, out var weapon_id))
commands_list.Add("/give " + weapon_id + " lv" + weapon.Level + "r" + weapon.RefinementLevel);
else
missingItems.Add(weapon.Name);
// TODO: Implement command to give weapon directly to character in Grasscutter
}
}
if (good.Artifacts != null)
{
foreach (var artifact in good.Artifacts)
{
// Format: set rarity slot
if (!GOODData.ArtifactCats.TryGetValue(artifact.SetName, out var artifact_set_id))
{
missingItems.Add(artifact.SetName);
continue;
}
var artifact_id = artifact_set_id.ToString() + artifact.Rarity.ToString() + GOODData.ArtifactSlotMap[artifact.GearSlot] + "4";
var artifact_mainStat_id = GOODData.ArtifactMainAttribution[artifact.MainStat];
var artifact_substats = "";
var artifact_substat_prefix = artifact.Rarity + "0";
int substat_count = 0;
foreach (var substat in artifact.SubStats)
{
if (substat.Value <= 0)
continue;
substat_count++;
var substat_key = substat.Stat;
var substat_key_id = GOODData.ArtifactSubAttribution[substat_key];
var substat_indices = ArtifactUtils.SplitSubstats(substat_key, artifact.Rarity, substat.Value);
foreach (int index in substat_indices)
{
artifact_substats += artifact_substat_prefix + substat_key_id + index.ToString() + " ";
}
}
// HACK: Add def+2 substat to counteract Grasscutter automatically adding another substat
if (substat_count == 4)
artifact_substats += "101081 ";
commands_list.Add("/give " + artifact_id + " lv" + artifact.Level + " " + artifact_mainStat_id + " " + artifact_substats);
// TODO: Implement command to give artifact directly to character in Grasscutter
}
}
// TODO: Materials
//if (good.Materials != null)
//{
// foreach (var material in good.Materials)
// {
// }
//}
var msg = string.Format("Loaded {0} Characters\nLoaded {1} Weapons\nLoaded {2} Artifacts\n",
good.Characters?.Count ?? 0,
good.Weapons?.Count ?? 0,
good.Artifacts?.Count ?? 0
);
if (missingItems.Count > 0)
{
msg += string.Format("There are {0} pieces of data that cannot be parsed, including:\n{1}",
missingItems.Count,
string.Join("\n", missingItems.Take(10)));
if (missingItems.Count > 10)
msg += "......";
}
msg += "Do you want to start?";
if (DialogResult.Yes != MessageBox.Show(msg, Resources.Tips, MessageBoxButtons.YesNo, MessageBoxIcon.Information))
return;
if (await RunCommands(commands_list.ToArray()))
MessageBox.Show(Resources.GOODImportSuccess);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void CmbLanguage_SelectedIndexChanged(object sender, EventArgs e) private void CmbLanguage_SelectedIndexChanged(object sender, EventArgs e)
{ {
@ -1093,31 +1216,41 @@ namespace GrasscutterTools.Forms
private async void BtnInvokeOpenCommand_Click(object sender, EventArgs e) private async void BtnInvokeOpenCommand_Click(object sender, EventArgs e)
{ {
if (OC == null || !OC.CanInvoke) if (!BtnInvokeOpenCommand.Enabled) return;
{
ShowTip(Resources.RequireOpenCommandTip, BtnInvokeOpenCommand);
TCMain.SelectedTab = TPRemoteCall;
return;
}
if (TxtCommand.Text.Length < 2) if (TxtCommand.Text.Length < 2)
{ {
ShowTip(Resources.CommandContentCannotBeEmpty, TxtCommand); ShowTip(Resources.CommandContentCannotBeEmpty, TxtCommand);
return; return;
} }
await RunCommands(TxtCommand.Text);
}
private async Task<bool> RunCommands(params string[] commands)
{
if (OC == null || !OC.CanInvoke)
{
ShowTip(Resources.RequireOpenCommandTip, BtnInvokeOpenCommand);
TCMain.SelectedTab = TPRemoteCall;
return false;
}
ExpandCommandRunLog(); ExpandCommandRunLog();
BtnInvokeOpenCommand.Enabled = false;
BtnInvokeOpenCommand.Cursor = Cursors.WaitCursor;
int i = 0;
foreach (var command in commands)
{
TxtCommandRunLog.AppendText(">"); TxtCommandRunLog.AppendText(">");
TxtCommandRunLog.AppendText(TxtCommand.Text); TxtCommandRunLog.AppendText(command);
if (commands.Length > 1)
TxtCommandRunLog.AppendText($" ({++i}/{commands.Length})");
TxtCommandRunLog.AppendText(Environment.NewLine); TxtCommandRunLog.AppendText(Environment.NewLine);
var cmd = TxtCommand.Text.Substring(1); var cmd = command.Substring(1);
var btn = sender as Button;
btn.Enabled = false;
try try
{ {
var msg = await OC.Invoke(cmd); var msg = await OC.Invoke(cmd);
TxtCommandRunLog.AppendText(string.IsNullOrEmpty(msg) ? "OK" : msg); TxtCommandRunLog.AppendText(string.IsNullOrEmpty(msg) ? "OK" : msg);
TxtCommandRunLog.AppendText(Environment.NewLine); TxtCommandRunLog.AppendText(Environment.NewLine);
//ShowTip(string.IsNullOrEmpty(msg) ? "OK" : msg, btn);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -1125,10 +1258,13 @@ namespace GrasscutterTools.Forms
TxtCommandRunLog.AppendText(ex.Message); TxtCommandRunLog.AppendText(ex.Message);
TxtCommandRunLog.AppendText(Environment.NewLine); TxtCommandRunLog.AppendText(Environment.NewLine);
MessageBox.Show(ex.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(ex.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
} }
TxtCommandRunLog.ScrollToCaret(); TxtCommandRunLog.ScrollToCaret();
btn.Cursor = Cursors.Default; }
btn.Enabled = true; BtnInvokeOpenCommand.Cursor = Cursors.Default;
BtnInvokeOpenCommand.Enabled = true;
return true;
} }
private const int TxtCommandRunLogMinHeight = 150; private const int TxtCommandRunLogMinHeight = 150;
@ -1332,6 +1468,7 @@ namespace GrasscutterTools.Forms
GrpRemoteCommand.Enabled = false; GrpRemoteCommand.Enabled = false;
BtnInvokeOpenCommand.Focus(); BtnInvokeOpenCommand.Focus();
ShowTip(Resources.ConnectedTip, BtnInvokeOpenCommand); ShowTip(Resources.ConnectedTip, BtnInvokeOpenCommand);
ButtonOpenGOODImport.Enabled = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -1412,6 +1549,5 @@ namespace GrasscutterTools.Forms
} }
#endregion - - #endregion - -
} }
} }

View File

@ -856,4 +856,7 @@ Therefore, the quest can be added and finished, but not necessarily work.</value
<data name="ChkIncludeUID.Text" xml:space="preserve"> <data name="ChkIncludeUID.Text" xml:space="preserve">
<value>Include UID</value> <value>Include UID</value>
</data> </data>
<data name="ButtonOpenGOODImport.Text" xml:space="preserve">
<value>Import GOOD</value>
</data>
</root> </root>

File diff suppressed because it is too large Load Diff

View File

@ -218,7 +218,7 @@
<value>Подключить</value> <value>Подключить</value>
</data> </data>
<data name="LblConsoleTip.Font" type="System.Drawing.Font, System.Drawing"> <data name="LblConsoleTip.Font" type="System.Drawing.Font, System.Drawing">
<value>微软雅黑, 8pt, style=Italic</value> <value>Microsoft YaHei, 8pt, style=Italic</value>
</data> </data>
<data name="LblConsoleTip.Location" type="System.Drawing.Point, System.Drawing"> <data name="LblConsoleTip.Location" type="System.Drawing.Point, System.Drawing">
<value>15, 34</value> <value>15, 34</value>
@ -397,7 +397,7 @@
<value>False</value> <value>False</value>
</data> </data>
<data name="LblTp.Font" type="System.Drawing.Font, System.Drawing"> <data name="LblTp.Font" type="System.Drawing.Font, System.Drawing">
<value>微软雅黑, 8pt</value> <value>Microsoft YaHei, 8pt</value>
</data> </data>
<data name="LblTp.Location" type="System.Drawing.Point, System.Drawing"> <data name="LblTp.Location" type="System.Drawing.Point, System.Drawing">
<value>6, 89</value> <value>6, 89</value>
@ -980,4 +980,7 @@
<data name="$this.Text" xml:space="preserve"> <data name="$this.Text" xml:space="preserve">
<value>GrasscutterTools - перевод Юрий Дворецкий</value> <value>GrasscutterTools - перевод Юрий Дворецкий</value>
</data> </data>
<data name="ButtonOpenGOODImport.Text" xml:space="preserve">
<value>импорт GOOD</value>
</data>
</root> </root>

View File

@ -406,4 +406,7 @@
<data name="TPHome.Text" xml:space="preserve"> <data name="TPHome.Text" xml:space="preserve">
<value>主頁</value> <value>主頁</value>
</data> </data>
<data name="ButtonOpenGOODImport.Text" xml:space="preserve">
<value>導入GOOD檔案</value>
</data>
</root> </root>

View File

@ -0,0 +1,94 @@
/**
* Grasscutter Tools
* Copyright (C) 2022 jie65535
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
**/
using Newtonsoft.Json;
namespace GrasscutterTools.GOOD
{
/// <summary>
/// Artifact data representation
/// Doc: https://frzyc.github.io/genshin-optimizer/#/doc
/// Modified from https://github.com/Andrewthe13th/Inventory_Kamera/blob/master/InventoryKamera/game/Artifact.cs
/// </summary>
public class Artifact
{
/// <summary>
/// e.g. "GladiatorsFinale"
/// </summary>
[JsonProperty("setKey")]
public string SetName { get; set; }
/// <summary>
/// //e.g. "plume"
/// type SlotKey = "flower" | "plume" | "sands" | "goblet" | "circlet"
/// </summary>
[JsonProperty("slotKey")]
public string GearSlot { get; set; }
/// <summary>
/// 1-5 inclusive
/// </summary>
[JsonProperty("rarity")]
public int Rarity { get; set; }
/// <summary>
/// mainStatKey
/// </summary>
[JsonProperty("mainStatKey")]
public string MainStat { get; set; }
/// <summary>
/// 0-20 inclusive
/// </summary>
[JsonProperty("level")]
public int Level { get; set; }
/// <summary>
/// substats
/// </summary>
[JsonProperty("substats")]
public SubStat[] SubStats { get; set; }
/// <summary>
/// where "" means not equipped.
/// </summary>
[JsonProperty("location")]
public string EquippedCharacter { get; set; }
/// <summary>
/// Whether the artifact is locked in game.
/// </summary>
[JsonProperty("lock")]
public bool Lock { get; set; }
public struct SubStat
{
/// <summary>
/// e.g. "critDMG_"
/// </summary>
[JsonProperty("key")]
public string Stat { get; set; }
/// <summary>
/// e.g. 19.4
/// </summary>
[JsonProperty("value")]
public double Value { get; set; }
}
}
}

View File

@ -0,0 +1,72 @@
/**
* Grasscutter Tools
* Copyright (C) 2022 jie65535
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
**/
using Newtonsoft.Json;
namespace GrasscutterTools.GOOD
{
/// <summary>
/// Character data representation
/// Doc: https://frzyc.github.io/genshin-optimizer/#/doc
/// Modified from https://github.com/Andrewthe13th/Inventory_Kamera/blob/master/InventoryKamera/game/Character.cs
/// </summary>
public class Character
{
/// <summary>
/// e.g. "Rosaria"
/// </summary>
[JsonProperty("key")]
public string Name { get; set; }
/// <summary>
/// 1-90 inclusive
/// </summary>
[JsonProperty("level")]
public int Level { get; set; }
/// <summary>
/// 0-6 inclusive
/// </summary>
[JsonProperty("constellation")]
public int Constellation { get; set; }
/// <summary>
/// 0-6 inclusive. need to disambiguate 80/90 or 80/80
/// </summary>
[JsonProperty("ascension")]
public int Ascension { get; set; }
/// <summary>
/// does not include boost from constellations. 1-15 inclusive
/// </summary>
[JsonProperty("talent")]
public Talents Talents { get; set; }
}
public struct Talents
{
[JsonProperty("auto")]
public int Auto { get; set; }
[JsonProperty("skill")]
public int Skill { get; set; }
[JsonProperty("burst")]
public int Burst { get; set; }
}
}

View File

@ -0,0 +1,63 @@
/**
* Grasscutter Tools
* Copyright (C) 2022 jie65535
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
**/
using System.Collections.Generic;
using Newtonsoft.Json;
namespace GrasscutterTools.GOOD
{
/// <summary>
/// Genshin Open Object Description (GOOD)
/// Doc: https://frzyc.github.io/genshin-optimizer/#/doc
/// Modified from https://github.com/Andrewthe13th/Inventory_Kamera/blob/master/InventoryKamera/data/GOOD.cs
///
/// Available for
/// https://frzyc.github.io/genshin-optimizer/
/// https://github.com/Andrewthe13th/Inventory_Kamera
/// https://genshin.aspirine.su/
/// https://seelie.me/
/// https://github.com/daydreaming666/Amenoma
/// https://www.mona-uranai.com/
/// https://genshin.mingyulab.com/
/// https://genshin-center.com/
/// </summary>
public class GOOD
{
[JsonProperty("format")]
public string Format { get; set; }
[JsonProperty("version")]
public int Version { get; set; }
[JsonProperty("source")]
public string Source { get; set; }
[JsonProperty("weapons", DefaultValueHandling = DefaultValueHandling.Ignore)]
public List<Weapon> Weapons { get; set; }
[JsonProperty("artifacts", DefaultValueHandling = DefaultValueHandling.Ignore)]
public List<Artifact> Artifacts { get; set; }
[JsonProperty("characters", DefaultValueHandling = DefaultValueHandling.Ignore)]
public List<Character> Characters { get; set; }
[JsonProperty("materials", DefaultValueHandling = DefaultValueHandling.Ignore)]
public Dictionary<string, int> Materials { get; set; }
}
}

View File

@ -0,0 +1,107 @@
/**
* Grasscutter Tools
* Copyright (C) 2022 jie65535
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
**/
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using GrasscutterTools.Game;
using GrasscutterTools.Properties;
namespace GrasscutterTools.GOOD
{
public static class GOODData
{
static GOODData()
{
var cultureInfo = CultureInfo.GetCultureInfo("en-US");
var regex = new Regex(@"[\W]", RegexOptions.Compiled);
Dictionary<string, int> ToGOODMap(ItemMap itemMap)
{
var dic = new Dictionary<string, int>(itemMap.Count);
for (int i = 0; i < itemMap.Count; i++)
{
var name = itemMap.Names[i];
var pascalCase = cultureInfo.TextInfo.ToTitleCase(name);
var nameGOOD = regex.Replace(pascalCase, string.Empty);
dic.Add(nameGOOD, itemMap.Ids[i]);
}
return dic;
}
var artifactCats = new ItemMap(Resources.ResourceManager.GetString("ArtifactCat", cultureInfo));
var avatars = new ItemMap(Resources.ResourceManager.GetString("Avatar", cultureInfo));
var weapons = new ItemMap(Resources.ResourceManager.GetString("Weapon", cultureInfo));
ArtifactCats = ToGOODMap(artifactCats);
Avatars = ToGOODMap(avatars);
Weapons = ToGOODMap(weapons);
}
public static Dictionary<string, int> ArtifactCats { get; private set; }
public static Dictionary<string, string> ArtifactSlotMap = new Dictionary<string, string> {
{"goblet", "1"}, {"plume", "2"}, {"circlet", "3"}, {"flower", "4"}, {"sands", "5"}
};
public static Dictionary<string, int> ArtifactMainAttribution { get; } = new Dictionary<string, int>
{
{ "hp" , 10001 },
{ "hp_" , 10002 },
{ "atk" , 10003 },
{ "atk_" , 10004 },
{ "def" , 10005 },
{ "def_" , 10006 },
{ "enerRech_" , 10007 },
{ "eleMas" , 10008 },
{ "critRate_" , 13007 },
{ "critDMG_" , 13008 },
{ "heal_" , 13009 },
{ "pyro_dmg_" , 15008 },
{ "electro_dmg_" , 15009 },
{ "cryo_dmg_" , 15010 },
{ "hydro_dmg_" , 15011 },
{ "anemo_dmg_" , 15012 },
{ "geo_dmg_" , 15013 },
{ "dendro_dmg_" , 15014 },
{ "physical_dmg_", 15015 },
};
public static Dictionary<string, int> ArtifactSubAttribution { get; } = new Dictionary<string, int>
{
{ "hp" , 102 },
{ "hp_" , 103 },
{ "atk" , 105 },
{ "atk_" , 106 },
{ "def" , 108 },
{ "def_" , 109 },
{ "critRate_", 120 },
{ "critDMG_" , 122 },
{ "enerRech_", 123 },
{ "eleMas" , 124 },
};
public static Dictionary<string, int> Avatars { get; private set; }
public static Dictionary<string, int> Weapons { get; private set; }
}
}

View File

@ -0,0 +1,68 @@
/**
* Grasscutter Tools
* Copyright (C) 2022 jie65535
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
**/
using System.ComponentModel;
using Newtonsoft.Json;
namespace GrasscutterTools.GOOD
{
/// <summary>
/// Weapon data representation
/// Doc: https://frzyc.github.io/genshin-optimizer/#/doc
/// Modified from https://github.com/Andrewthe13th/Inventory_Kamera/blob/master/InventoryKamera/game/Weapon.cs
/// </summary>
public class Weapon
{
/// <summary>
/// e.g. "CrescentPike"
/// </summary>
[JsonProperty("key")]
public string Name { get; set; }
/// <summary>
/// 1-90 inclusive
/// </summary>
[JsonProperty("level")]
public int Level { get; set; }
/// <summary>
/// 0-6 inclusive. need to disambiguate 80/90 or 80/80
/// </summary>
[JsonProperty("ascension")]
public int AscensionLevel { get; set; }
/// <summary>
/// 1-5 inclusive
/// </summary>
[JsonProperty("refinement")]
public int RefinementLevel { get; set; }
/// <summary>
/// where "" means not equipped.
/// </summary>
[JsonProperty("location")]
[DefaultValue("")]
public string EquippedCharacter { get; set; }
/// <summary>
/// Whether the weapon is locked in game.
/// </summary>
[JsonProperty("lock")]
public bool Lock { get; set; }
}
}

View File

@ -38,7 +38,7 @@ namespace GrasscutterTools.Game
if (si > 0 && int.TryParse(line.Substring(0, si).Trim(), out int id)) if (si > 0 && int.TryParse(line.Substring(0, si).Trim(), out int id))
{ {
var name = line.Substring(si + 1).Trim(); var name = line.Substring(si + 1).Trim();
if (!string.IsNullOrEmpty(name)) if (!string.IsNullOrEmpty(name) && name != "null")
{ {
//IdMap[id] = name; //IdMap[id] = name;
//NameMap[name] = id; //NameMap[name] = id;

View File

@ -234,6 +234,11 @@
<Compile Include="Game\SetStatsCommand.cs" /> <Compile Include="Game\SetStatsCommand.cs" />
<Compile Include="Game\TextMapData.cs" /> <Compile Include="Game\TextMapData.cs" />
<Compile Include="Github\ReleaseAPI.cs" /> <Compile Include="Github\ReleaseAPI.cs" />
<Compile Include="GOOD\GOOD.cs" />
<Compile Include="GOOD\Artifact.cs" />
<Compile Include="GOOD\Character.cs" />
<Compile Include="GOOD\GOODData.cs" />
<Compile Include="GOOD\Weapon.cs" />
<Compile Include="OpenCommand\OpenCommandAPI.cs" /> <Compile Include="OpenCommand\OpenCommandAPI.cs" />
<Compile Include="MultiLanguage.cs" /> <Compile Include="MultiLanguage.cs" />
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
@ -243,6 +248,7 @@
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
</Compile> </Compile>
<Compile Include="Utils\ArtifactUtils.cs" />
<Compile Include="Utils\HttpHelper.cs" /> <Compile Include="Utils\HttpHelper.cs" />
<EmbeddedResource Include="Forms\FormGachaBannerEditor2.en-us.resx"> <EmbeddedResource Include="Forms\FormGachaBannerEditor2.en-us.resx">
<DependentUpon>FormGachaBannerEditor2.cs</DependentUpon> <DependentUpon>FormGachaBannerEditor2.cs</DependentUpon>

View File

@ -67,25 +67,6 @@ namespace GrasscutterTools.Properties {
///28010104: 将军蟹 ///28010104: 将军蟹
///28010105: 薄红蟹 ///28010105: 薄红蟹
///28010106: 螃蟹 ///28010106: 螃蟹
///28020101: 雪狐
///28020102: 红狐
///28020103: 送礼雪狐
///28020104: 送大礼雪狐
///28020105: 雪狐
///28020106: 红狐
///28020201: 松鼠
///28030101: 蓝翎鹭
///28030102: 菫鹮
///28030201: 茶羽鹰
///28030202: 棕翎鹰
///28030203: 石鸢
///28030204: 白练鹰
///28050101: 风晶蝶
///28050102: 岩晶蝶
///28050103: 冰晶蝶
///28050104: 雷晶蝶
///28050105: 珊瑚蝶
///28050301: 吉光虫
///28010201: 蓝角蜥 ///28010201: 蓝角蜥
///28010202: 红角蜥 ///28010202: 红角蜥
///28010203: 绿角蜥 ///28010203: 绿角蜥
@ -95,7 +76,25 @@ namespace GrasscutterTools.Properties {
///28010207: 嗜髓蜥 ///28010207: 嗜髓蜥
///28010301: 青蛙 ///28010301: 青蛙
///28010302: 泥蛙 ///28010302: 泥蛙
///2801030 [字符串的其余部分被截断]&quot;; 的本地化字符串。 ///28010303: 蓝蛙
///28010401: 藤纹陆鳗鳗
///28010402: 深海鳗鳗
///28010403: 赤鳍陆鳗鳗
///28020101: 雪狐
///28020102: 红狐
///28020103: 送礼雪狐
///28020104: 送大礼雪狐
///28020105: 雪狐
///28020106: 红狐
///28020201: 松鼠
///28020301: 野林猪
///28020302: 小野林猪
///28020303: 雪猪
///28020304: 「大雪猪王」
///28020305: 冰冻雪猪
///28020306: 雪猪
///28020307: 野林猪
///28020308: 冰冻雪 [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary> /// </summary>
internal static string Animal { internal static string Animal {
get { get {
@ -302,40 +301,55 @@ namespace GrasscutterTools.Properties {
} }
/// <summary> /// <summary>
/// 查找类似 10000001 : 凯特 /// 查找类似 1002: 神里绫华
///10000002 : 神里绫华 ///1003: 琴
///10000003 : 琴 ///1005: 空
///10000005 : 旅行者 ///1006: 丽莎
///10000006 : 丽莎 ///1007: 荧
///10000007 : 旅行者 ///1014: 芭芭拉
///10000014 : 芭芭拉 ///1015: 凯亚
///10000015 : 凯亚 ///1016: 迪卢克
///10000016 : 迪卢克 ///1020: 雷泽
///10000020 : 雷泽 ///1021: 安柏
///10000021 : 安柏 ///1022: 温迪
///10000022 : 温迪 ///1023: 香菱
///10000023 : 香菱 ///1024: 北斗
///10000024 : 北斗 ///1025: 行秋
///10000025 : 行秋 ///1026: 魈
///10000026 : 魈 ///1027: 凝光
///10000027 : 凝光 ///1029: 可莉
///10000029 : 可莉 ///1030: 钟离
///10000030 : 钟离 ///1031: 菲谢尔
///10000031 : 菲谢尔 ///1032: 班尼特
///10000032 : 班尼特 ///1033: 达达利亚
///10000033 : 达达利亚 ///1034: 诺艾尔
///10000034 : 诺艾尔 ///1035: 七七
///10000035 : 七七 ///1036: 重云
///10000036 : 重云 ///1037: 甘雨
///10000037 : 甘雨 ///1038: 阿贝多
///10000038 : 阿贝多 ///1039: 迪奥娜
///10000039 : 迪奥娜 ///1041: 莫娜
///10000041 : 莫娜 ///1042: 刻晴
///10000042 : 刻晴 ///1043: 砂糖
///10000043 : 砂糖 ///1044: 辛焱
///10000044 : 辛焱 ///1045: 罗莎莉亚
///10000045 : 罗莎莉亚 ///1046: 胡桃
///1000 [字符串的其余部分被截断]&quot;; 的本地化字符串。 ///1047: 枫原万叶
///1048: 烟绯
///1049: 宵宫
///1050: 托马
///1051: 优菈
///1052: 雷电将军
///1053: 早柚
///1054: 珊瑚宫心海
///1055: 五郎
///1056: 九条裟罗
///1057: 荒泷一斗
///1058: 八重神子
///1060: 夜兰
///1062: 埃洛伊
///1063: 申鹤
///1064: 云堇 /// [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary> /// </summary>
internal static string Avatar { internal static string Avatar {
get { get {
@ -484,21 +498,23 @@ namespace GrasscutterTools.Properties {
/// <summary> /// <summary>
/// 查找类似 无敌 /// 查找类似 无敌
////prop godmode on ////prop god on
///无限体力 ///无限体力
////prop nostamina on ////prop ns on
///无限能量 ///无限能量
////prop unlimitedenergy on ////prop ue on
///升到60级 ///升到60级
////give 102 x1880200 ////give 102 x1880200
///设置世界等级 ///设置世界等级
////prop worldlevel 8 ////prop wl 8
///一键解锁深渊 ///一键解锁深渊
////prop abyss 12 ////prop ut 12
///设置纪行等级
////prop bp 50
///设置好感等级 ///设置好感等级
////setfetterlevel 10 ////setfetterlevel 10
///奶 ///奶
////heal ////h
///自杀 ///自杀
////kill 0 ////kill 0
///全队充能 ///全队充能
@ -524,11 +540,11 @@ namespace GrasscutterTools.Properties {
///清空全部角色命之座(需重登) ///清空全部角色命之座(需重登)
////resetconst all ////resetconst all
///清空背包 ///清空背包
////clear all ////clear all lv90 r5 5*
///清空武器 ///清空武器
////clear wp ////clear wp lv90 r5 5*
///清空圣遗物 ///清空圣遗物
////clea [字符串的其余部分被截断]&quot;; 的本地化字符串。 /// [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary> /// </summary>
internal static string CustomCommands { internal static string CustomCommands {
get { get {
@ -580,7 +596,9 @@ namespace GrasscutterTools.Properties {
///061: 鬼门斗宴 ///061: 鬼门斗宴
///065: 出尘入世 ///065: 出尘入世
///071: 华紫樱绯 ///071: 华紫樱绯
///076: 苍流踏花 的本地化字符串。 ///076: 苍流踏花
///081: 素霓伣天
/// 的本地化字符串。
/// </summary> /// </summary>
internal static string GachaBennerPrefab { internal static string GachaBennerPrefab {
get { get {
@ -588,6 +606,33 @@ namespace GrasscutterTools.Properties {
} }
} }
/// <summary>
/// 查找类似 导入成功! 的本地化字符串。
/// </summary>
internal static string GOODImportSuccess {
get {
return ResourceManager.GetString("GOODImportSuccess", resourceCulture);
}
}
/// <summary>
/// 查找类似 是否导入 的本地化字符串。
/// </summary>
internal static string GOODImportText {
get {
return ResourceManager.GetString("GOODImportText", resourceCulture);
}
}
/// <summary>
/// 查找类似 导入GOOD档案 的本地化字符串。
/// </summary>
internal static string GOODImportTitle {
get {
return ResourceManager.GetString("GOODImportTitle", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 帮助 的本地化字符串。 /// 查找类似 帮助 的本地化字符串。
/// </summary> /// </summary>
@ -638,49 +683,52 @@ namespace GrasscutterTools.Properties {
} }
/// <summary> /// <summary>
/// 查找类似 101 : 角色经验 /// 查找类似 101: 角色经验
///102 : 冒险阅历 ///102: 冒险阅历
///103 : 星尘 ///103: 星尘
///104 : 星辉 ///104: 星辉
///105 : 好感经验 ///105: 好感经验
///106 : 原粹树脂 ///106: 原粹树脂
///107 : 传说钥匙 ///107: 传说钥匙
///108 : (test)天体推演 ///108: (test)天体推演
///109 : 熄星能量 ///109: 熄星能量
///110 : 熄星精粹 ///110: 熄星精粹
///111 : 微光精粹 ///111: 微光精粹
///112 : 温暖精粹 ///112: 温暖精粹
///113 : 奇迹精粹 ///113: 奇迹精粹
///114 : 铁钱 ///114: 铁钱
///115 : 平安玉符 ///115: 平安玉符
///116 : 节庆热度 ///116: 节庆热度
///117 : 奇术符 ///117: 奇术符
///118 : 庆典巡回券 ///118: 庆典巡回券
///119 : 奇趣协力券 ///119: 奇趣协力券
///120 : 纯水真心 ///120: 纯水真心
///121 : 信任值 ///121: 信任值
///122 : 碎果数据 ///122: 碎果数据
///123 : 迷踪币 ///123: 迷踪币
///124 : 亮闪闪的漂流物 ///124: 亮闪闪的漂流物
///125 : 迷你「羽球」 ///125: 迷你「羽球」
///126 : 神秘齿轮 ///126: 神秘齿轮
///127 : 鸣雷霰子 ///127: 鸣雷霰子
///128 : 鸣雷纯晶 ///128: 鸣雷纯晶
///129 : 弈棋术经验 ///129: 弈棋术经验
///130 : 灵妙玉符 ///130: 灵妙玉符
///131 : 逐月节节庆热度 ///131: 逐月节节庆热度
///132 : 残悴之式札 ///132: 残悴之式札
///133 : 虚损之拓本 ///133: 虚损之拓本
///134 : 朽裂之庚牌 ///134: 朽裂之庚牌
///135 : 踏雪章 ///135: 踏雪章
///136 : 克险章 ///136: 克险章
///137 : 逢福玉符 ///137: 逢福玉符
///138 : 完璧玉符 ///138: 完璧玉符
///139 : 降魔玉符 ///139: 降魔玉符
///140 : 幽蕴砺石 ///140: 幽蕴砺石
///142 : 战策碎珀 ///142: 战策碎珀
///201 : 原石 ///201: 原石
///2 [字符串的其余部分被截断]&quot;; 的本地化字符串。 ///202: 摩拉
///203: 创世结晶
///204: 洞天宝钱
///210: 原粹精珀(废弃 [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary> /// </summary>
internal static string Item { internal static string Item {
get { get {
@ -794,32 +842,28 @@ namespace GrasscutterTools.Properties {
///server.* ///server.*
///server.** ///server.**
///player.changescene ///player.changescene
///player.clearinv ///player.clear
///player.enterdungeon ///player.enterdungeon
///player.enterdungeon.others
///player.give ///player.give
///player.giveall ///player.give.others
///player.giveart
///player.givechar
///player.godmode ///player.godmode
///player.heal ///player.heal
///player.heal.others
///player.killcharacter ///player.killcharacter
///player.killcharacter.others
///player.quest
///player.quest.others
///player.resetconstellation ///player.resetconstellation
///player.resetconstellation.others
///player.setfetterlevel ///player.setfetterlevel
///player.setfetterlevel.others
///player.setprop
///player.setprop.others
///player.setstats ///player.setstats
///player.setstats.others
///player.settalent ///player.settalent
///player.setworldlevel ///play [字符串的其余部分被截断]&quot;; 的本地化字符串。
///player.teleport
///player.tpall
///player.weather
///server.broadcast
///server.coop
///server.drop
///server.kick
///server.killall
///server.reload
///server.resetshop
///server.sendmail
///server.sendmessage /// [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary> /// </summary>
internal static string Permissions { internal static string Permissions {
get { get {
@ -837,27 +881,28 @@ namespace GrasscutterTools.Properties {
} }
/// <summary> /// <summary>
/// 查找类似 30302 : 女神像解锁$HIDDEN - /// 查找类似 30302: 女神像解锁$HIDDEN -
///30303 : 女神像解锁$HIDDEN - ///30303: 女神像解锁$HIDDEN -
///30304 : 女神像解锁$HIDDEN - ///30304: 女神像解锁$HIDDEN -
///30305 : 女神像解锁$HIDDEN - ///30305: 女神像解锁$HIDDEN -
///30306 : 女神像解锁$HIDDEN - ///30306: 女神像解锁$HIDDEN -
///30307 : 女神像解锁$HIDDEN - ///30307: 女神像解锁$HIDDEN -
///30308 : 女神像解锁$HIDDEN - ///30308: 女神像解锁$HIDDEN -
///30309 : 女神像解锁$HIDDEN - ///30309: 女神像解锁$HIDDEN -
///30310 : 女神像解锁$HIDDEN - ///30310: 女神像解锁$HIDDEN -
///30311 : 女神像解锁$HIDDEN - ///30311: 女神像解锁$HIDDEN -
///30312 : 女神像解锁$HIDDEN - ///30312: 女神像解锁$HIDDEN -
///30313 : 女神像解锁$HIDDEN - ///30313: 女神像解锁$HIDDEN -
///30314 : 女神像解锁$HIDDEN - ///30314: 女神像解锁$HIDDEN -
///30315 : 女神像解锁$HIDDEN - ///30315: 女神像解锁$HIDDEN -
///30316 : 女神像解锁$HIDDEN - ///30316: 女神像解锁$HIDDEN -
///30317 : 女神像解锁$HIDDEN - ///30317: 女神像解锁$HIDDEN -
///30600 : 昔日的风 - 在庙宇门口跟安柏见面 ///30600: 昔日的风 - 在庙宇门口跟安柏见面
///30601 : 昔日的风 - 与安柏对话 ///30601: 昔日的风 - 与安柏对话
///30602 : 昔日的风 - 进入庙宇 ///30602: 昔日的风 - 进入庙宇
///30603 : 昔日的风 - 探索庙宇深处 ///30603: 昔日的风 - 探索庙宇深处
///30604 : 昔日的风 - 退出秘境 [字符串的其余部分被截断]&quot;; 的本地化字符串。 ///30604: 昔日的风 - 退出秘境
///30607: 昔日的风 - (test [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary> /// </summary>
internal static string Quest { internal static string Quest {
get { get {
@ -884,20 +929,20 @@ namespace GrasscutterTools.Properties {
} }
/// <summary> /// <summary>
/// 查找类似 1 : 提瓦特 /// 查找类似 1: 提瓦特
///2 : 提瓦特 ///2: 提瓦特
///3 : 提瓦特 ///3: 提瓦特
///4 : 金苹果群岛 ///4: 金苹果群岛
///5 : 渊下宫 ///5: 渊下宫
///6 : 层岩巨渊·地下矿区 ///6: 层岩巨渊·地下矿区
///7 : 三界路飨祭 ///7: 三界路飨祭
///2001 : 罗浮洞 ///2001: 罗浮洞
///2002 : 翠黛峰 ///2002: 翠黛峰
///2003 : 清琼岛 ///2003: 清琼岛
///2004 : 绘绮庭 ///2004: 绘绮庭
///2201 : 尘歌壶室内_蒙德 ///2201: 尘歌壶室内_蒙德
///2202 : 尘歌壶室内_璃月 ///2202: 尘歌壶室内_璃月
///2203 : 尘歌壶室内_稻妻 ///2203: 尘歌壶室内_稻妻
///20008: 深入狼之殿 ///20008: 深入狼之殿
///20008: 丘丘人大本营(test) ///20008: 丘丘人大本营(test)
///20008: 丘丘人巢穴(test) ///20008: 丘丘人巢穴(test)
@ -915,7 +960,7 @@ namespace GrasscutterTools.Properties {
///1001: 移动平台性能测试(test) ///1001: 移动平台性能测试(test)
///50003: 战斗性能测试(test) ///50003: 战斗性能测试(test)
///50004: 电桩电源白盒(test) ///50004: 电桩电源白盒(test)
///50027: [字符串的其余部分被截断]&quot;; 的本地化字符串。 ///50027: 圣遗物新因子测试关卡3(t [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary> /// </summary>
internal static string Scene { internal static string Scene {
get { get {
@ -978,43 +1023,47 @@ namespace GrasscutterTools.Properties {
} }
/// <summary> /// <summary>
/// 查找类似 11101 : 无锋剑 /// 查找类似 11101: 无锋剑
///11201 : 银剑 ///11201: 银剑
///11301 : 冷刃 ///11301: 冷刃
///11302 : 黎明神剑 ///11302: 黎明神剑
///11303 : 旅行剑 ///11303: 旅行剑
///11304 : 暗铁剑 ///11304: 暗铁剑
///11305 : 吃虎鱼刀 ///11305: 吃虎鱼刀
///11306 : 飞天御剑 ///11306: 飞天御剑
///11401 : 西风剑 ///11401: 西风剑
///11402 : 笛剑 ///11402: 笛剑
///11403 : 祭礼剑 ///11403: 祭礼剑
///11404 : 宗室长剑 ///11404: 宗室长剑
///11405 : 匣里龙吟 ///11405: 匣里龙吟
///11406 : 试作斩岩 ///11406: 试作斩岩
///11407 : 铁蜂刺 ///11407: 铁蜂刺
///11408 : 黑岩长剑 ///11408: 黑岩长剑
///11409 : 黑剑 ///11409: 黑剑
///11410 : 暗巷闪光 ///11410: 暗巷闪光
///11412 : 降临之剑 ///11412: 降临之剑
///11413 : 腐殖之剑 ///11413: 腐殖之剑
///11414 : 天目影打刀 ///11414: 天目影打刀
///11415 : 辰砂之纺锤 ///11415: 辰砂之纺锤
///11501 : 风鹰剑 ///11501: 风鹰剑
///11502 : 天空之刃 ///11502: 天空之刃
///11503 : 苍古自由之誓 ///11503: 苍古自由之誓
///11504 : 斫峰之刃 ///11504: 斫峰之刃
///11505 : 磐岩结绿 ///11505: 磐岩结绿
///11509 : 雾切之回光 ///11507: 凭虚
///11510 : 波乱月白经津 ///11509: 雾切之回光
///12101 : 训练大剑 ///11510: 波乱月白经津
///12201 : 佣兵重剑 ///12101: 训练大剑
///12301 : 铁影阔剑 ///12201: 佣兵重剑
///12302 : 沐浴龙血的剑 ///12301: 铁影阔剑
///12303 : 白铁大剑 ///12302: 沐浴龙血的剑
///12304 : 石英大剑 ///12303: 白铁大剑
///12305 : 以理服人 ///12304: 石英大剑
///12306 : 飞天大御剑 /// [字符串的其余部分被截断]&quot;; 的本地化字符串。 ///12305: 以理服人
///12306: 飞天大御剑
///12401: 西风大剑
///12402: 钟剑
///1 [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary> /// </summary>
internal static string Weapon { internal static string Weapon {
get { get {

View File

@ -255,4 +255,14 @@ Do you want to check for updates? Selecting No will no longer remind you of this
<data name="WeaponColor" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="WeaponColor" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\WeaponColor.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value> <value>..\Resources\WeaponColor.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data> </data>
<data name="GOODImportText" xml:space="preserve">
<value>Do you wish to import </value>
</data>
<data name="GOODImportTitle" xml:space="preserve">
<value>Import GOOD dump file</value>
</data>
<data name="GOODImportSuccess" xml:space="preserve">
<value>Import success!</value>
</data>
</root> </root>

View File

@ -184,6 +184,9 @@
<data name="GachaBennerPrefab" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="GachaBennerPrefab" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\zh-cn\GachaBennerPrefab.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value> <value>..\Resources\zh-cn\GachaBennerPrefab.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data> </data>
<data name="SettingSaveError" xml:space="preserve">
<value>保存设置时异常:</value>
</data>
<data name="Help" xml:space="preserve"> <data name="Help" xml:space="preserve">
<value>帮助</value> <value>帮助</value>
</data> </data>
@ -243,9 +246,6 @@
<data name="SettingLoadError" xml:space="preserve"> <data name="SettingLoadError" xml:space="preserve">
<value>加载设置时异常:</value> <value>加载设置时异常:</value>
</data> </data>
<data name="SettingSaveError" xml:space="preserve">
<value>保存设置时异常:</value>
</data>
<data name="Tips" xml:space="preserve"> <data name="Tips" xml:space="preserve">
<value>提示</value> <value>提示</value>
</data> </data>
@ -264,4 +264,13 @@
<data name="WeaponColor" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="WeaponColor" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\WeaponColor.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value> <value>..\Resources\WeaponColor.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data> </data>
<data name="GOODImportText" xml:space="preserve">
<value>是否导入 </value>
</data>
<data name="GOODImportTitle" xml:space="preserve">
<value>导入GOOD档案</value>
</data>
<data name="GOODImportSuccess" xml:space="preserve">
<value>导入成功!</value>
</data>
</root> </root>

View File

@ -252,4 +252,13 @@
<data name="WeaponColor" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="WeaponColor" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\WeaponColor.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value> <value>..\Resources\WeaponColor.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data> </data>
<data name="GOODImportText" xml:space="preserve">
<value>是否導入 </value>
</data>
<data name="GOODImportTitle" xml:space="preserve">
<value>導入GOOD檔案</value>
</data>
<data name="GOODImportSuccess" xml:space="preserve">
<value>導入成功!</value>
</data>
</root> </root>

View File

@ -0,0 +1,222 @@
/**
* Grasscutter Tools
* Copyright (C) 2022 jie65535
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
**/
using System;
using System.Collections.Generic;
using System.Linq;
namespace GrasscutterTools.Utils
{
class SubstatSumEquality : IEqualityComparer<List<KeyValuePair<int, double>>>
{
public bool Equals(List<KeyValuePair<int, double>> left, List<KeyValuePair<int, double>> right)
{
if (sum_substat(left) == sum_substat(right))
return true;
else
return false;
}
public int GetHashCode(List<KeyValuePair<int, double>> dict)
{
return sum_substat(dict).GetHashCode();
}
public static double sum_substat(List<KeyValuePair<int, double>> dict)
{
double sum = 0;
foreach (KeyValuePair<int, double> kvp in dict)
{
sum += kvp.Value;
}
return sum;
}
}
class ArtifactUtils
{
public static Dictionary<string, double[][]> substats_rolls = new Dictionary<string, double[][]>
{
{
"hp",
new double[][] {
new double[] {23.9, 29.88},
new double[] {50.19, 60.95, 71.7},
new double[] {100.38, 114.72, 129.06, 143.4},
new double[] {167.3, 191.2, 215.1, 239},
new double[] {209.13, 239, 268.88, 298.75}
}
},
{
"hp_",
new double[][] {
new double[] {1.17, 1.46},
new double[] {1.63, 1.98, 2.33},
new double[] {2.45, 2.8, 3.15, 3.5},
new double[] {3.26, 3.73, 4.2, 4.66},
new double[] {4.08, 4.66, 5.25, 5.83}
}
},
{
"atk",
new double[][] {
new double[] {1.56, 1.95},
new double[] {3.27, 3.97, 4.67},
new double[] {6.54, 7.47, 8.4, 9.34},
new double[] {10.89, 12.45, 14, 15.56},
new double[] {13.62, 15.56, 17.51, 19.45 }
}
},
{
"atk_",
new double[][] {
new double[] {1.17, 1.46},
new double[] {1.63, 1.98, 2.33},
new double[] {2.45, 2.8, 3.15, 3.5},
new double[] {3.26, 3.73, 4.2, 4.66},
new double[] {4.08, 4.66, 5.25, 5.83}
}
},
{
"def",
new double[][] {
new double[] {1.85, 2.31},
new double[] {3.89, 4.72, 5.56},
new double[] {10, 11.11, 7.78, 8.89},
new double[] {12.96, 14.82, 16.67, 18.52},
new double[] {16.2, 18.52, 20.83, 23.15}
}
},
{
"def_",
new double[][] {
new double[] {1.46, 1.82},
new double[] {2.04, 2.48, 2.91},
new double[] {3.06, 3.5, 3.93, 4.37},
new double[] {4.08, 4.66, 5.25, 5.83},
new double[] {5.1, 5.83, 6.56, 7.29}
}
},
{
"critRate_",
new double[][] {
new double[] {.78, .97},
new double[] {1.09, 1.32, 1.55},
new double[] {1.63, 1.86, 2.1, 2.33},
new double[] {2.18, 2.49, 2.8, 3.11},
new double[] {2.72, 3.11, 3.5, 3.89}
}
},
{
"critDMG_",
new double[][] {
new double[] {1.55, 1.94},
new double[] {2.18, 2.64, 3.11},
new double[] {3.26, 3.73, 4.2, 4.66},
new double[] {4.35, 4.97, 5.6, 6.22},
new double[] {5.44, 6.22, 6.99, 7.77}
}
},
{
"eleMas",
new double[][] {
new double[] {4.66, 5.83},
new double[] {6.53, 7.93, 9.33},
new double[] {11.19, 12.59, 13.99, 9.79},
new double[] {13.06, 14.92, 16.79, 18.65},
new double[] {16.32, 18.65, 20.98, 23.31}
}
},
{
"enerRech_",
new double[][] {
new double[] {1.3, 1.62},
new double[] {1.81, 2.2, 2.59},
new double[] {2.72, 3.11, 3.5, 3.89},
new double[] {3.63, 4.14, 4.66, 5.18},
new double[] {4.53, 5.18, 5.83, 6.48}
}
}
};
// ArtifactSub -> Rarity -> Stat value -> Stat index list
public static Dictionary<string, Dictionary<int, List<KeyValuePair<double, int[]>>>> substats_dict;
public static int[] SplitSubstats(string type, int rarity, double value)
{
if (!substats_initiated)
{
InitSubstats();
substats_initiated = true;
}
double last_stat_diff = 99999;
int[] last_stat_list = { 4, 4, 4, 4, 4, 4 };
foreach (KeyValuePair<double, int[]> value_to_list in substats_dict[type][rarity])
{
if (Math.Abs(value - value_to_list.Key) >= last_stat_diff)
{
return last_stat_list;
}
last_stat_diff = value - value_to_list.Key;
last_stat_list = value_to_list.Value;
}
// Default, should never happen
return last_stat_list;
}
private static void InitSubstats()
{
substats_dict = new Dictionary<string, Dictionary<int, List<KeyValuePair<double, int[]>>>>();
foreach (KeyValuePair<string, double[][]> stat_block_info in substats_rolls)
{
string stat_name = stat_block_info.Key;
substats_dict[stat_name] = new Dictionary<int, List<KeyValuePair<double, int[]>>>();
for (int rarity_index = 0; rarity_index < stat_block_info.Value.Length; rarity_index++)
{
var substat_options = new List<KeyValuePair<int, double>>();
// Substat index == 0 means no substat upgrade
substat_options.Add(new KeyValuePair<int, double>(0, 0));
for (int substat_index = 0; substat_index < substats_rolls[stat_name][rarity_index].Length; substat_index++)
{
substat_options.Add(new KeyValuePair<int, double>(substat_index+1, substats_rolls[stat_name][rarity_index][substat_index]));
}
var substat_sum_data = (from s1 in substat_options from s2 in substat_options from s3 in substat_options from s4 in substat_options from s5 in substat_options from s6 in substat_options select new { s1, s2, s3, s4, s5, s6 })
.Select(x => new List<KeyValuePair<int, double>> { x.s1, x.s2, x.s3, x.s4, x.s5, x.s6 })
.Distinct(new SubstatSumEquality());
var stats_map = new List<KeyValuePair<double, int[]>>();
foreach (List<KeyValuePair<int, double>> val in substat_sum_data.ToArray().OrderBy(list => SubstatSumEquality.sum_substat(list)))
{
var index_list = new List<int>();
foreach (KeyValuePair<int, double> pair in val)
{
if (pair.Key != 0)
index_list.Add(pair.Key);
}
stats_map.Add(new KeyValuePair<double, int[]>(SubstatSumEquality.sum_substat(val), index_list.ToArray()));
}
substats_dict[stat_name][rarity_index + 1] = stats_map;
}
}
}
private static bool substats_initiated = false;
}
}