<commit_before>﻿using Fiddler;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;

namespace Grandcypher
{
	public class WeaponHooker
	{
		#region EventHandler
		/// <summary>
		/// 이벤트 핸들러
		/// </summary>
		public delegate void EventHandler();
		public EventHandler WeaponListLoad;
		public EventHandler LoadingEnd;
		public EventHandler DeckLoadingEnd;
		public EventHandler ProgressBar;
		#endregion

		public LimitedValue ProgressStatus { get; set; }
		public Dictionary<int, WeaponInfo> MasterBinList { get; set; }
		public List<WeaponInfo> WeaponLists { get; set; }
		public List<NpcInfo> NPCList { get; set; }
		public WeaponInfo MainWeapon { get; set; }
		public Skills SkillCounter { get; set; }
		public List<string> SkillList { get; set; }

		public bool IsConcilioExist { get; private set; }
		public bool IsVisExist { get; private set; }

		private bool DeckIsEnd { get; set; }
		private bool ListIsEnd { get; set; }
		private List<decimal> ConBahaList { get; set; }
		private List<decimal> VisBahaList { get; set; }
		public void SessionReader(Session oS)
		{
			if (oS.PathAndQuery.StartsWith("/weapon/list") && oS.oResponse.MIMEType == "application/json")
				ListDetail(oS);
			if (oS.PathAndQuery.StartsWith("/weapon/enhancement_materials") && oS.oResponse.MIMEType == "application/json")
				ListDetail(oS);
			if (oS.PathAndQuery.StartsWith("/party/weapon/pc") && oS.oResponse.MIMEType == "application/json")
				ListDetail(oS);
			if (!oS.PathAndQuery.Contains("decks") && oS.PathAndQuery.StartsWith("/party/deck") && oS.oResponse.MIMEType == "application/json")
				DeckDetail(oS);
			if (oS.PathAndQuery.StartsWith("/npc/enhancement_materials") && oS.oResponse.MIMEType == "application/json")
				ListDetail(oS);
			if (oS.PathAndQuery.StartsWith("/weapon/weapon") && oS.oResponse.MIMEType == "application/json")
				WeaponDetail(oS, false);
			if (oS.PathAndQuery.StartsWith("/weapon/weapon_base") && oS.oResponse.MIMEType == "application/json")
				WeaponDetail(oS, false);
			if (oS.PathAndQuery.StartsWith("/enhancement_weapon/enhancement") && oS.oResponse.MIMEType == "application/json")
				WeaponDetail(oS);
		}
		/// <summary>
		/// 무기 정보에 접근할때 자동적으로 무기의 레벨을 저장한다.
		/// </summary>
		/// <param name="oS"></param>
		private void WeaponDetail(Session oS, bool IsEnhance = true)
		{
			JObject jsonFull = JObject.Parse(oS.GetResponseBodyAsString()) as JObject;
			dynamic temp = jsonFull;
			if (!IsEnhance)
			{
				dynamic master = temp.master;
				dynamic param = temp.param;
				if (temp.id != null)
				{
					int SkillLv = param.skill_level;
					int MasterId = master.id;
					if (SkillLv <= 1) return;
					if (MasterId == 1039900000 || MasterId == 1029900000) return;
					int id = temp.id;
					dynamic skill1 = temp.skill1;
					dynamic skill2 = temp.skill2;

					if (skill1.comment != null) this.WeaponLvSave(id, 1, SkillLv);
					if (skill2.comment != null) this.WeaponLvSave(id, 2, SkillLv);
				}
			}
			else
			{
				dynamic detail = temp.detail;
				JObject NewInfo = (JObject)temp["new"];
				if (detail.id != null)
				{
					int ParamId = detail.id;
					int MasterId = detail.master.id;
					int NewSkillLv = (int)NewInfo["skill_level"];

					if (NewSkillLv <= 1) return;
					if (MasterId == 1039900000 || MasterId == 1029900000) return;

					dynamic skill1 = detail.skill1;
					dynamic skill2 = detail.skill2;

					if (skill1.comment != null) this.WeaponLvSave(ParamId, 1, NewSkillLv);
					if (skill2.comment != null) this.WeaponLvSave(ParamId, 2, NewSkillLv);
				}
			}
		}
		#region List
		/// <summary>
		/// 기본 무기 리스트. 강화/리스트/창고가 포함됨
		/// </summary>
		/// <param name="oS"></param>

		private void ListDetail(Session oS)
		{
			this.WeaponListLoad();
			this.ListIsEnd = false;
			this.DeckIsEnd = false;
			if (this.WeaponLists == null)
				this.WeaponLists = new List<WeaponInfo>();
			else
			{
				this.WeaponLists.Clear();
				this.WeaponLists.TrimExcess();
			}
			JObject jsonFull = JObject.Parse(oS.GetResponseBodyAsString()) as JObject;
			dynamic test = jsonFull;
			dynamic list = test.list;


			List<dynamic> weaponList = new List<dynamic>();

			for (int i = 0; i < list.Count; i++)
			{
				weaponList.Add(list[i]);
			}

			this.ProgressStatus = new LimitedValue();
			this.ProgressStatus.Max = weaponList.Count;
			this.ProgressStatus.Min = 0;
			this.ProgressStatus.Current = 0;

			this.ProgressBar();

			for (int i = 0; i < weaponList.Count; i++)
			{
				dynamic tempIndex = weaponList[i].master;
				dynamic tempparam = weaponList[i].param;
				WeaponInfo temp = new WeaponInfo();

				temp.MasterId = tempIndex.id;
				temp.ParamId = tempparam.id;//무기 스킬레벨등을 저장하고 구별하기 위한 부분

				temp.ItemName = GrandcypherClient.Current.Translations.GetTranslation(Translations.TranslationType.WeaponList, "", TranslateKind.Google, temp.MasterId);
				if (temp.ItemName != string.Empty)
				{
					temp.Element = GrandcypherClient.Current.Translations.GetTranslation(Translations.TranslationType.Element, "", TranslateKind.Google, temp.MasterId);
					temp.Kind = GrandcypherClient.Current.Translations.GetTranslation(Translations.TranslationType.WeaponType, "", TranslateKind.Google, temp.MasterId);
				}
				else
				{
					int msid = temp.MasterId;
					temp = MasterInfoLoad(temp.MasterId,Convert.ToInt32(tempparam.id));

					if (temp.SkillName1 != string.Empty) temp.SkillDetail1 = GrandcypherClient.Current.Translations.GetSkillInfo(temp.SkillName1, true);
					else temp.SkillDetail1 = string.Empty;
					if (temp.SkillName2 != string.Empty) temp.SkillDetail2 = GrandcypherClient.Current.Translations.GetSkillInfo(temp.SkillName2, true);
					else temp.SkillDetail2 = string.Empty;
				}
				temp.is_used = weaponList[i].is_used;

				temp = this.InputSkillInfo(temp);

				temp.SkillLv1 = WeaponLvLoad(temp.ParamId, 1);
				temp.SkillLv2 = WeaponLvLoad(temp.ParamId, 2);

				if (temp.SkillName1 == string.Empty || temp.SkillName1 == null) temp.vSkillLv1 = Visibility.Collapsed;
				else temp.vSkillLv1 = Visibility.Visible;
				if (temp.SkillName2 == string.Empty || temp.SkillName2 == null) temp.vSkillLv2 = Visibility.Collapsed;
				else temp.vSkillLv2 = Visibility.Visible;

				WeaponLists.Add(temp);
				this.ProgressStatus.Current++;
				this.ProgressBar();
			}
			this.ListIsEnd = true;
			this.LoadingEnd();
		}
		#endregion

		#region 덱 편성
		/// <summary>
		/// 덱 편성 화면. 공인계산기 포함
		/// </summary>
		/// <param name="oS"></param>
		private void DeckDetail(Session oS)
		{
			this.ListIsEnd = false;
			this.DeckIsEnd = false;

			this.WeaponListLoad();
			int MasterAttribute = 0;

			this.SkillCounter = new Skills();
			this.ConBahaList = new List<decimal>();
			this.VisBahaList = new List<decimal>();

			if (this.WeaponLists == null)
				this.WeaponLists = new List<WeaponInfo>();
			else
			{
				this.WeaponLists.Clear();
				this.WeaponLists.TrimExcess();
			}

			if (this.NPCList == null)
				this.NPCList = new List<NpcInfo>();
			else
			{
				this.NPCList.Clear();
				this.NPCList.TrimExcess();
			}

			JObject jsonFull = JObject.Parse(oS.GetResponseBodyAsString()) as JObject;
			dynamic test = jsonFull;
			dynamic list = test.deck.pc.weapons;
			dynamic npcList = test.deck.npc;

			if (test.deck.pc.skill.count > 0)
			{
				this.SkillList = new List<string>();
				dynamic skilllist = test.deck.pc.skill.description;
				foreach (var item in skilllist)
				{
					JProperty SkillProperty = item;
					var Firsts = SkillProperty.First;
					string SkillComment = (string)Firsts["comment"];
					int over = (int)Firsts["over"];

					if (over > 1) SkillList.Add("◎ " + GrandcypherClient.Current.ScenarioHooker.Translator(SkillComment, GrandcypherClient.Current.ScenarioHooker.TranslateSite) + " + " + over.ToString());
					else SkillList.Add("◎ " + GrandcypherClient.Current.ScenarioHooker.Translator(SkillComment, GrandcypherClient.Current.ScenarioHooker.TranslateSite));
				}
			}
			if (test.deck.pc.param.attribute != null)
			{
				MasterAttribute = Convert.ToInt32(test.deck.pc.param.attribute);
			}
			this.ProgressStatus = new LimitedValue();
			this.ProgressStatus.Max = 15;
			this.ProgressStatus.Min = 0;
			this.ProgressStatus.Current = 0;

			//캐릭터의 속성을 구별할 방법이 외부 DB를 추가로 만드는 방법밖에 없기때문에 일단 모두 같은 속성으로 간주. 
			//즉 디 오더 그랑데나 속성 불일치 종족파티를 쓰는 유저는 이 계산기를 사용할수없음
			for (int i = 1; i < 6; i++)
			{
				NpcInfo npc = new NpcInfo();
				string temp = i.ToString();
				JObject jobject = (JObject)npcList[temp];
				JObject param;
				JObject master;
				try
				{
					param = (JObject)jobject["param"];
					master = (JObject)jobject["master"];
				}
				catch
				{
					this.NPCList.Add(npc);
					continue;
				}
				npc.name = (string)master["name"];
				npc.attack = (int)param["attack"];
				this.NPCList.Add(npc);
				this.ProgressStatus.Current++;
				this.ProgressBar();
			}

			for (int i = 1; i < 11; i++)
			{
				WeaponInfo deck = new WeaponInfo();
				string temp = i.ToString();
				JObject jobject = (JObject)list[temp];
				JObject master;
				JObject param;
				try
				{
					master = (JObject)jobject["master"];
					param = (JObject)jobject["param"];
				}
				catch
				{
					deck.vSkillLv1 = Visibility.Collapsed;
					deck.vSkillLv2 = Visibility.Collapsed;
					WeaponLists.Add(deck);
					continue;
				}
				deck.MasterId = (int)master["id"];
				deck.ParamId = (int)param["id"];//무기 스킬레벨등을 저장하고 구별하기 위한 부분
				deck.ItemName = GrandcypherClient.Current.Translations.GetTranslation(Translations.TranslationType.WeaponList, "", TranslateKind.Google, deck.MasterId);
				if (deck.ItemName == string.Empty)
				{
					int msid = deck.MasterId;
					deck = MasterInfoLoad(deck.MasterId, (int)param["id"]);
					if (deck.SkillName1 != string.Empty) deck.SkillDetail1 = GrandcypherClient.Current.Translations.GetSkillInfo(deck.SkillName1, true);
					else deck.SkillDetail1 = string.Empty;
					if (deck.SkillName2 != string.Empty) deck.SkillDetail2 = GrandcypherClient.Current.Translations.GetSkillInfo(deck.SkillName2, true);
					else deck.SkillDetail2 = string.Empty;
				}
				deck.vSkillLv1 = Visibility.Collapsed;
				deck.vSkillLv2 = Visibility.Collapsed;

				deck = this.InputSkillInfo(deck);
				deck.attribute = (int)master["attribute"];
				if (!deck.IsManual) deck.Kind = GrandcypherClient.Current.Translations.GetTranslation(Translations.TranslationType.WeaponType, "", TranslateKind.Google, deck.MasterId);

				if (i == 1)
				{
					MainWeapon = deck;
				}
				else WeaponLists.Add(deck);

				this.ProgressStatus.Current++;
				this.ProgressBar();
			}


			for (int i = 0; i < WeaponLists.Count; i++)
			{
				if (WeaponLists[i].SkillAttribute1 == MasterAttribute
					|| WeaponLists[i].SkillAttribute1 >= 7)
					this.SumAtt(WeaponLists[i].GeneralType1, WeaponLists[i]);
				if (WeaponLists[i].SkillAttribute2 == MasterAttribute
					|| WeaponLists[i].SkillAttribute2 >= 7)
					this.SumAtt(WeaponLists[i].GeneralType2, WeaponLists[i], true);
			}
			if (MainWeapon.SkillAttribute1 == MasterAttribute
				|| MainWeapon.SkillAttribute1 >= 7)
				this.SumAtt(MainWeapon.GeneralType1, MainWeapon);
			if (MainWeapon.SkillAttribute2 == MasterAttribute
				|| MainWeapon.SkillAttribute2 >= 7)
				this.SumAtt(MainWeapon.GeneralType2, MainWeapon, true);

			this.SkillCounter.Baha += this.TotalBaha(this.ConBahaList);
			this.SkillCounter.Baha += this.TotalBaha(this.VisBahaList);

			this.DeckIsEnd = true;
			if (test.deck.pc.param != null) SkillCounter.BasicAttack = test.deck.pc.param.attack;
			this.DeckLoadingEnd();
		}
		private decimal TotalBaha(List<decimal> target)
		{
			if (target.Count == 0) return 0;

			decimal result = target[0];
			for (int i = 1; i < target.Count; i++)
			{
				if (result < target[i]) result = target[i];
			}
			return result;
		}
		/// <summary>
		/// 무기 정보를 받아 무기의 스킬배수를 계산
		/// </summary>
		/// <param name="General"></param>
		/// <param name="weapon"></param>
		/// <param name="IsSecond"></param>
		private void SumAtt(int General, WeaponInfo weapon, bool IsSecond = false)
		{
			decimal att = 0;
			if (!IsSecond)
			{
				switch (General)
				{
					case 1://공격
						switch (weapon.AttackType1)
						{
							case 1://일반
								this.SkillCounter.Noramal += this.RaiseSkillLevel(weapon.Skill_Rank1, weapon.SkillLv1, weapon.Is_Double1);
								break;
							case 2://언노운
								this.SkillCounter.Unknown += this.RaiseSkillLevel(weapon.Skill_Rank1, weapon.SkillLv1, weapon.Is_Double1);
								break;
							case 3://스트렝스
								this.SkillCounter.Str += this.RaiseSkillLevel(weapon.Skill_Rank1, weapon.SkillLv1, weapon.Is_Double1);
								break;
							case 4://세이빙
								this.SkillCounter.Saving += this.RaiseSkillLevel(weapon.Skill_Rank1, weapon.SkillLv1, weapon.Is_Double1);
								break;
							case 5://마그나
								this.SkillCounter.Magna += this.RaiseSkillLevel(weapon.Skill_Rank1, weapon.SkillLv1, weapon.Is_Double1);
								break;
							case 6://절대치 상승
								this.SkillCounter.staticAtt += weapon.Skill_Rank1;
								break;
							case 7://vis
								if (weapon.SkillLv1 == 10)
								{
									att += 30;
								}
								else
								{
									att += 20;//기본
									att += weapon.SkillLv1;//스킬레벨
								}
								this.VisBahaList.Add(att);
								this.IsVisExist = true;
								break;
							case 8://con
								if (weapon.SkillLv1 == 10)
								{
									att += 15;
								}
								else
								{
									att += 10;//기본
									att += weapon.SkillLv1 * 0.5m;//스킬레벨 * 0.5
								}
								this.ConBahaList.Add(att);
								this.IsConcilioExist = true;
								break;
						}
						break;
					case 3://배수
						break;
				}
			}
			else
			{
				switch (General)
				{
					case 1://공격
						switch (weapon.AttackType2)
						{
							case 1://일반
								this.SkillCounter.Noramal += this.RaiseSkillLevel(weapon.Skill_Rank2, weapon.SkillLv2, weapon.Is_Double2);
								break;
							case 2://언노운
								this.SkillCounter.Unknown += this.RaiseSkillLevel(weapon.Skill_Rank2, weapon.SkillLv2, weapon.Is_Double2);
								break;
							case 3://스트렝스
								this.SkillCounter.Str += this.RaiseSkillLevel(weapon.Skill_Rank2, weapon.SkillLv2, weapon.Is_Double2);
								break;
							case 4://세이빙
								this.SkillCounter.Saving += this.RaiseSkillLevel(weapon.Skill_Rank2, weapon.SkillLv2, weapon.Is_Double2);
								break;
							case 5://마그나
								this.SkillCounter.Magna += this.RaiseSkillLevel(weapon.Skill_Rank2, weapon.SkillLv2, weapon.Is_Double2);
								break;
							case 6://절대치 상승
								this.SkillCounter.staticAtt += weapon.Skill_Rank2;
								break;
							case 7://vis
								if (weapon.SkillLv2 == 10) att += 30;
								else
								{
									att += 20;
									att += weapon.SkillLv2;
								}
								this.VisBahaList.Add(att);
								this.IsVisExist = true;
								break;
							case 8://con
								if (weapon.SkillLv2 == 10) att += 15;
								else
								{
									att += 10;
									att += weapon.SkillLv2 * 0.5m;
								}
								this.ConBahaList.Add(att);
								this.IsConcilioExist = true;
								break;
						}
						break;
					case 3://배수
						break;
				}
			}
		}
		private decimal RaiseSkillLevel(int Rank, int SkillLv, bool IsDouble)
		{
			decimal ans = 0;
			switch (Rank)//기본값 설정
			{
				case 1:
					ans = 0;
					break;
				case 2:
					ans = 2;
					break;
				case 3:
					if (IsDouble) ans = 6;
					else ans = 5;
					break;
			}
			if (SkillLv < 11)//스킬레벨이 10이하인 경우엔 모든 증가폭이 1이다
			{
				return ans + SkillLv;
			}
			else//스킬레벨이 11이상인 경우엔 증가폭이 다르게 나타난다
			{
				ans += 10;
				switch (Rank)//추가치를 더한다.
				{
					case 1:
						return ans += (SkillLv - 10) * 0.4m;
					case 2:
						return ans += (SkillLv - 10) * 0.5m;
					case 3:
						if (IsDouble)
							return ans += (SkillLv - 10) * 0.8m;
						else
							return ans += (SkillLv - 10) * 0.6m;
				}
			}
			return 0;
		}
		public void Reload()
		{
			if (this.DeckIsEnd) this.DeckLoadingEnd();
			if (this.ListIsEnd) this.LoadingEnd();
		}
		/// <summary>
		/// 마스터 리스트를 불러온다
		/// </summary>
		public void MasterInfoListLoad()
		{
			string MainFolder = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
			var binPath = Path.Combine(MainFolder, "Data", "MasterWeapon.bin");

			var items = new Dictionary<int, WeaponInfo>();

			if (File.Exists(binPath))
			{
				var bytes = File.ReadAllBytes(binPath);
				using (var memoryStream = new MemoryStream(bytes))
				using (var reader = new BinaryReader(memoryStream))
				{
					while (memoryStream.Position < memoryStream.Length)
					{
						int paramID = reader.ReadInt32();
						var item = new WeaponInfo
						{
							attribute = reader.ReadInt32(),
							WeaponType = reader.ReadInt32(),
							ItemName = reader.ReadString(),
							SkillName1 = reader.ReadString(),
							SkillName2 = reader.ReadString(),
						};
						items.Add(paramID, item);
					}
					memoryStream.Dispose();
					memoryStream.Close();
					reader.Dispose();
					reader.Close();
				}
				//파일 읽기 종료
			}
			this.MasterBinList = items;
		}
		/// <summary>
		/// 어플리케이션 구동시 불러온 마스터 리스트를 기반으로 데이터를 검색해서 자동으로 세팅.
		/// </summary>
		/// <param name="MasterId"></param>
		/// <returns></returns>
		private WeaponInfo MasterInfoLoad(int MasterId,int paramId)
		{
			if (this.MasterBinList == null)
			{
				return new WeaponInfo//스킬 리스트에 직접 접근하지 못하므로 일단 스킬명은 String.Empty로 설정<commit_msg>바하무트 웨폰 스킬 계산 수정<commit_after>﻿using Fiddler;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows;

namespace Grandcypher
{
	public class WeaponHooker
	{
		#region EventHandler
		/// <summary>
		/// 이벤트 핸들러
		/// </summary>
		public delegate void EventHandler();
		public EventHandler WeaponListLoad;
		public EventHandler LoadingEnd;
		public EventHandler DeckLoadingEnd;
		public EventHandler ProgressBar;
		#endregion

		public LimitedValue ProgressStatus { get; set; }
		public Dictionary<int, WeaponInfo> MasterBinList { get; set; }
		public List<WeaponInfo> WeaponLists { get; set; }
		public List<NpcInfo> NPCList { get; set; }
		public WeaponInfo MainWeapon { get; set; }
		public Skills SkillCounter { get; set; }
		public List<string> SkillList { get; set; }

		public bool IsConcilioExist { get; private set; }
		public bool IsVisExist { get; private set; }

		private bool DeckIsEnd { get; set; }
		private bool ListIsEnd { get; set; }
		private List<decimal> ConBahaList { get; set; }
		private List<decimal> VisBahaList { get; set; }
		public void SessionReader(Session oS)
		{
			if (oS.PathAndQuery.StartsWith("/weapon/list") && oS.oResponse.MIMEType == "application/json")
				ListDetail(oS);
			if (oS.PathAndQuery.StartsWith("/weapon/enhancement_materials") && oS.oResponse.MIMEType == "application/json")
				ListDetail(oS);
			if (oS.PathAndQuery.StartsWith("/party/weapon/pc") && oS.oResponse.MIMEType == "application/json")
				ListDetail(oS);
			if (!oS.PathAndQuery.Contains("decks") && oS.PathAndQuery.StartsWith("/party/deck") && oS.oResponse.MIMEType == "application/json")
				DeckDetail(oS);
			if (oS.PathAndQuery.StartsWith("/npc/enhancement_materials") && oS.oResponse.MIMEType == "application/json")
				ListDetail(oS);
			if (oS.PathAndQuery.StartsWith("/weapon/weapon") && oS.oResponse.MIMEType == "application/json")
				WeaponDetail(oS, false);
			if (oS.PathAndQuery.StartsWith("/weapon/weapon_base") && oS.oResponse.MIMEType == "application/json")
				WeaponDetail(oS, false);
			if (oS.PathAndQuery.StartsWith("/enhancement_weapon/enhancement") && oS.oResponse.MIMEType == "application/json")
				WeaponDetail(oS);
		}
		/// <summary>
		/// 무기 정보에 접근할때 자동적으로 무기의 레벨을 저장한다.
		/// </summary>
		/// <param name="oS"></param>
		private void WeaponDetail(Session oS, bool IsEnhance = true)
		{
			JObject jsonFull = JObject.Parse(oS.GetResponseBodyAsString()) as JObject;
			dynamic temp = jsonFull;
			if (!IsEnhance)
			{
				dynamic master = temp.master;
				dynamic param = temp.param;
				if (temp.id != null)
				{
					int SkillLv = param.skill_level;
					int MasterId = master.id;
					if (SkillLv <= 1) return;
					if (MasterId == 1039900000 || MasterId == 1029900000) return;
					int id = temp.id;
					dynamic skill1 = temp.skill1;
					dynamic skill2 = temp.skill2;

					if (skill1.comment != null) this.WeaponLvSave(id, 1, SkillLv);
					if (skill2.comment != null) this.WeaponLvSave(id, 2, SkillLv);
				}
			}
			else
			{
				dynamic detail = temp.detail;
				JObject NewInfo = (JObject)temp["new"];
				if (detail.id != null)
				{
					int ParamId = detail.id;
					int MasterId = detail.master.id;
					int NewSkillLv = (int)NewInfo["skill_level"];

					if (NewSkillLv <= 1) return;
					if (MasterId == 1039900000 || MasterId == 1029900000) return;

					dynamic skill1 = detail.skill1;
					dynamic skill2 = detail.skill2;

					if (skill1.comment != null) this.WeaponLvSave(ParamId, 1, NewSkillLv);
					if (skill2.comment != null) this.WeaponLvSave(ParamId, 2, NewSkillLv);
				}
			}
		}
		#region List
		/// <summary>
		/// 기본 무기 리스트. 강화/리스트/창고가 포함됨
		/// </summary>
		/// <param name="oS"></param>

		private void ListDetail(Session oS)
		{
			this.WeaponListLoad();
			this.ListIsEnd = false;
			this.DeckIsEnd = false;
			if (this.WeaponLists == null)
				this.WeaponLists = new List<WeaponInfo>();
			else
			{
				this.WeaponLists.Clear();
				this.WeaponLists.TrimExcess();
			}
			JObject jsonFull = JObject.Parse(oS.GetResponseBodyAsString()) as JObject;
			dynamic test = jsonFull;
			dynamic list = test.list;


			List<dynamic> weaponList = new List<dynamic>();

			for (int i = 0; i < list.Count; i++)
			{
				weaponList.Add(list[i]);
			}

			this.ProgressStatus = new LimitedValue();
			this.ProgressStatus.Max = weaponList.Count;
			this.ProgressStatus.Min = 0;
			this.ProgressStatus.Current = 0;

			this.ProgressBar();

			for (int i = 0; i < weaponList.Count; i++)
			{
				dynamic tempIndex = weaponList[i].master;
				dynamic tempparam = weaponList[i].param;
				WeaponInfo temp = new WeaponInfo();

				temp.MasterId = tempIndex.id;
				temp.ParamId = tempparam.id;//무기 스킬레벨등을 저장하고 구별하기 위한 부분

				temp.ItemName = GrandcypherClient.Current.Translations.GetTranslation(Translations.TranslationType.WeaponList, "", TranslateKind.Google, temp.MasterId);
				if (temp.ItemName != string.Empty)
				{
					temp.Element = GrandcypherClient.Current.Translations.GetTranslation(Translations.TranslationType.Element, "", TranslateKind.Google, temp.MasterId);
					temp.Kind = GrandcypherClient.Current.Translations.GetTranslation(Translations.TranslationType.WeaponType, "", TranslateKind.Google, temp.MasterId);
				}
				else
				{
					int msid = temp.MasterId;
					temp = MasterInfoLoad(temp.MasterId, Convert.ToInt32(tempparam.id));

					if (temp.SkillName1 != string.Empty) temp.SkillDetail1 = GrandcypherClient.Current.Translations.GetSkillInfo(temp.SkillName1, true);
					else temp.SkillDetail1 = string.Empty;
					if (temp.SkillName2 != string.Empty) temp.SkillDetail2 = GrandcypherClient.Current.Translations.GetSkillInfo(temp.SkillName2, true);
					else temp.SkillDetail2 = string.Empty;
				}
				temp.is_used = weaponList[i].is_used;

				temp = this.InputSkillInfo(temp);

				temp.SkillLv1 = WeaponLvLoad(temp.ParamId, 1);
				temp.SkillLv2 = WeaponLvLoad(temp.ParamId, 2);

				if (temp.SkillName1 == string.Empty || temp.SkillName1 == null) temp.vSkillLv1 = Visibility.Collapsed;
				else temp.vSkillLv1 = Visibility.Visible;
				if (temp.SkillName2 == string.Empty || temp.SkillName2 == null) temp.vSkillLv2 = Visibility.Collapsed;
				else temp.vSkillLv2 = Visibility.Visible;

				WeaponLists.Add(temp);
				this.ProgressStatus.Current++;
				this.ProgressBar();
			}
			this.ListIsEnd = true;
			this.LoadingEnd();
		}
		#endregion

		#region 덱 편성
		/// <summary>
		/// 덱 편성 화면. 공인계산기 포함
		/// </summary>
		/// <param name="oS"></param>
		private void DeckDetail(Session oS)
		{
			this.ListIsEnd = false;
			this.DeckIsEnd = false;

			this.WeaponListLoad();
			int MasterAttribute = 0;

			this.SkillCounter = new Skills();
			this.ConBahaList = new List<decimal>();
			this.VisBahaList = new List<decimal>();

			if (this.WeaponLists == null)
				this.WeaponLists = new List<WeaponInfo>();
			else
			{
				this.WeaponLists.Clear();
				this.WeaponLists.TrimExcess();
			}

			if (this.NPCList == null)
				this.NPCList = new List<NpcInfo>();
			else
			{
				this.NPCList.Clear();
				this.NPCList.TrimExcess();
			}

			JObject jsonFull = JObject.Parse(oS.GetResponseBodyAsString()) as JObject;
			dynamic test = jsonFull;
			dynamic list = test.deck.pc.weapons;
			dynamic npcList = test.deck.npc;

			if (test.deck.pc.skill.count > 0)
			{
				this.SkillList = new List<string>();
				dynamic skilllist = test.deck.pc.skill.description;
				foreach (var item in skilllist)
				{
					JProperty SkillProperty = item;
					var Firsts = SkillProperty.First;
					string SkillComment = (string)Firsts["comment"];
					int over = (int)Firsts["over"];

					if (over > 1) SkillList.Add("◎ " + GrandcypherClient.Current.ScenarioHooker.Translator(SkillComment, GrandcypherClient.Current.ScenarioHooker.TranslateSite) + " + " + over.ToString());
					else SkillList.Add("◎ " + GrandcypherClient.Current.ScenarioHooker.Translator(SkillComment, GrandcypherClient.Current.ScenarioHooker.TranslateSite));
				}
			}
			if (test.deck.pc.param.attribute != null)
			{
				MasterAttribute = Convert.ToInt32(test.deck.pc.param.attribute);
			}
			this.ProgressStatus = new LimitedValue();
			this.ProgressStatus.Max = 15;
			this.ProgressStatus.Min = 0;
			this.ProgressStatus.Current = 0;

			//캐릭터의 속성을 구별할 방법이 외부 DB를 추가로 만드는 방법밖에 없기때문에 일단 모두 같은 속성으로 간주. 
			//즉 디 오더 그랑데나 속성 불일치 종족파티를 쓰는 유저는 이 계산기를 사용할수없음
			for (int i = 1; i < 6; i++)
			{
				NpcInfo npc = new NpcInfo();
				string temp = i.ToString();
				JObject jobject = (JObject)npcList[temp];
				JObject param;
				JObject master;
				try
				{
					param = (JObject)jobject["param"];
					master = (JObject)jobject["master"];
				}
				catch
				{
					this.NPCList.Add(npc);
					continue;
				}
				npc.name = (string)master["name"];
				npc.attack = (int)param["attack"];
				this.NPCList.Add(npc);
				this.ProgressStatus.Current++;
				this.ProgressBar();
			}

			for (int i = 1; i < 11; i++)
			{
				WeaponInfo deck = new WeaponInfo();
				string temp = i.ToString();
				JObject jobject = (JObject)list[temp];
				JObject master;
				JObject param;
				try
				{
					master = (JObject)jobject["master"];
					param = (JObject)jobject["param"];
				}
				catch
				{
					deck.vSkillLv1 = Visibility.Collapsed;
					deck.vSkillLv2 = Visibility.Collapsed;
					WeaponLists.Add(deck);
					continue;
				}
				deck.MasterId = (int)master["id"];
				deck.ParamId = (int)param["id"];//무기 스킬레벨등을 저장하고 구별하기 위한 부분
				deck.ItemName = GrandcypherClient.Current.Translations.GetTranslation(Translations.TranslationType.WeaponList, "", TranslateKind.Google, deck.MasterId);
				if (deck.ItemName == string.Empty)
				{
					int msid = deck.MasterId;
					deck = MasterInfoLoad(deck.MasterId, (int)param["id"]);
					if (deck.SkillName1 != string.Empty) deck.SkillDetail1 = GrandcypherClient.Current.Translations.GetSkillInfo(deck.SkillName1, true);
					else deck.SkillDetail1 = string.Empty;
					if (deck.SkillName2 != string.Empty) deck.SkillDetail2 = GrandcypherClient.Current.Translations.GetSkillInfo(deck.SkillName2, true);
					else deck.SkillDetail2 = string.Empty;
				}
				deck.vSkillLv1 = Visibility.Collapsed;
				deck.vSkillLv2 = Visibility.Collapsed;

				deck = this.InputSkillInfo(deck);
				deck.attribute = (int)master["attribute"];
				if (!deck.IsManual) deck.Kind = GrandcypherClient.Current.Translations.GetTranslation(Translations.TranslationType.WeaponType, "", TranslateKind.Google, deck.MasterId);

				if (i == 1)
				{
					MainWeapon = deck;
				}
				else WeaponLists.Add(deck);

				this.ProgressStatus.Current++;
				this.ProgressBar();
			}


			for (int i = 0; i < WeaponLists.Count; i++)
			{
				if (WeaponLists[i].SkillAttribute1 == MasterAttribute
					|| WeaponLists[i].SkillAttribute1 >= 7)
					this.SumAtt(WeaponLists[i].GeneralType1, WeaponLists[i]);
				if (WeaponLists[i].SkillAttribute2 == MasterAttribute
					|| WeaponLists[i].SkillAttribute2 >= 7)
					this.SumAtt(WeaponLists[i].GeneralType2, WeaponLists[i], true);
			}
			if (MainWeapon.SkillAttribute1 == MasterAttribute
				|| MainWeapon.SkillAttribute1 >= 7)
				this.SumAtt(MainWeapon.GeneralType1, MainWeapon);
			if (MainWeapon.SkillAttribute2 == MasterAttribute
				|| MainWeapon.SkillAttribute2 >= 7)
				this.SumAtt(MainWeapon.GeneralType2, MainWeapon, true);

			this.SkillCounter.Baha += this.TotalBaha(this.ConBahaList);
			this.SkillCounter.Baha += this.TotalBaha(this.VisBahaList);

			this.DeckIsEnd = true;
			if (test.deck.pc.param != null) SkillCounter.BasicAttack = test.deck.pc.param.attack;
			this.DeckLoadingEnd();
		}
		private decimal TotalBaha(List<decimal> target)
		{
			if (target.Count == 0) return 0;

			decimal result = target[0];
			for (int i = 1; i < target.Count; i++)
			{
				if (result < target[i]) result = target[i];
			}
			return result;
		}
		/// <summary>
		/// 무기 정보를 받아 무기의 스킬배수를 계산
		/// </summary>
		/// <param name="General"></param>
		/// <param name="weapon"></param>
		/// <param name="IsSecond"></param>
		private void SumAtt(int General, WeaponInfo weapon, bool IsSecond = false)
		{
			decimal att = 0;
			if (!IsSecond)
			{
				switch (General)
				{
					case 1://공격
						switch (weapon.AttackType1)
						{
							case 1://일반
								this.SkillCounter.Noramal += this.RaiseSkillLevel(weapon.Skill_Rank1, weapon.SkillLv1, weapon.Is_Double1);
								break;
							case 2://언노운
								this.SkillCounter.Unknown += this.RaiseSkillLevel(weapon.Skill_Rank1, weapon.SkillLv1, weapon.Is_Double1);
								break;
							case 3://스트렝스
								this.SkillCounter.Str += this.RaiseSkillLevel(weapon.Skill_Rank1, weapon.SkillLv1, weapon.Is_Double1);
								break;
							case 4://세이빙
								this.SkillCounter.Saving += this.RaiseSkillLevel(weapon.Skill_Rank1, weapon.SkillLv1, weapon.Is_Double1);
								break;
							case 5://마그나
								this.SkillCounter.Magna += this.RaiseSkillLevel(weapon.Skill_Rank1, weapon.SkillLv1, weapon.Is_Double1);
								break;
							case 6://절대치 상승
								this.SkillCounter.staticAtt += weapon.Skill_Rank1;
								break;
							case 7://vis
								if (weapon.SkillLv1 == 10)
								{
									att += 30;
								}
								else
								{
									att += 20;//기본
									att += (weapon.SkillLv1 - 1);//스킬레벨
								}
								this.VisBahaList.Add(att);
								this.IsVisExist = true;
								break;
							case 8://con
								if (weapon.SkillLv1 == 10)
								{
									att += 15;
								}
								else
								{
									att += 10;//기본
									att += (weapon.SkillLv1 - 1) * 0.5m;//스킬레벨 * 0.5
								}
								this.ConBahaList.Add(att);
								this.IsConcilioExist = true;
								break;
						}
						break;
					case 3://배수
						break;
				}
			}
			else
			{
				switch (General)
				{
					case 1://공격
						switch (weapon.AttackType2)
						{
							case 1://일반
								this.SkillCounter.Noramal += this.RaiseSkillLevel(weapon.Skill_Rank2, weapon.SkillLv2, weapon.Is_Double2);
								break;
							case 2://언노운
								this.SkillCounter.Unknown += this.RaiseSkillLevel(weapon.Skill_Rank2, weapon.SkillLv2, weapon.Is_Double2);
								break;
							case 3://스트렝스
								this.SkillCounter.Str += this.RaiseSkillLevel(weapon.Skill_Rank2, weapon.SkillLv2, weapon.Is_Double2);
								break;
							case 4://세이빙
								this.SkillCounter.Saving += this.RaiseSkillLevel(weapon.Skill_Rank2, weapon.SkillLv2, weapon.Is_Double2);
								break;
							case 5://마그나
								this.SkillCounter.Magna += this.RaiseSkillLevel(weapon.Skill_Rank2, weapon.SkillLv2, weapon.Is_Double2);
								break;
							case 6://절대치 상승
								this.SkillCounter.staticAtt += weapon.Skill_Rank2;
								break;
							case 7://vis
								if (weapon.SkillLv2 == 10) att += 30;
								else
								{
									att += 20;
									att += weapon.SkillLv2;
								}
								this.VisBahaList.Add(att);
								this.IsVisExist = true;
								break;
							case 8://con
								if (weapon.SkillLv2 == 10) att += 15;
								else
								{
									att += 10;
									att += weapon.SkillLv2 * 0.5m;
								}
								this.ConBahaList.Add(att);
								this.IsConcilioExist = true;
								break;
						}
						break;
					case 3://배수
						break;
				}
			}
		}
		private decimal RaiseSkillLevel(int Rank, int SkillLv, bool IsDouble)
		{
			decimal ans = 0;
			switch (Rank)//기본값 설정
			{
				case 1:
					ans = 0;
					break;
				case 2:
					ans = 2;
					break;
				case 3:
					if (IsDouble) ans = 6;
					else ans = 5;
					break;
			}
			if (SkillLv < 11)//스킬레벨이 10이하인 경우엔 모든 증가폭이 1이다
			{
				return ans + SkillLv;
			}
			else//스킬레벨이 11이상인 경우엔 증가폭이 다르게 나타난다
			{
				ans += 10;
				switch (Rank)//추가치를 더한다.
				{
					case 1:
						return ans += (SkillLv - 10) * 0.4m;
					case 2:
						return ans += (SkillLv - 10) * 0.5m;
					case 3:
						if (IsDouble)
							return ans += (SkillLv - 10) * 0.8m;
						else
							return ans += (SkillLv - 10) * 0.6m;
				}
			}
			return 0;
		}
		public void Reload()
		{
			if (this.DeckIsEnd) this.DeckLoadingEnd();
			if (this.ListIsEnd) this.LoadingEnd();
		}
		/// <summary>
		/// 마스터 리스트를 불러온다
		/// </summary>
		public void MasterInfoListLoad()
		{
			string MainFolder = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
			var binPath = Path.Combine(MainFolder, "Data", "MasterWeapon.bin");

			var items = new Dictionary<int, WeaponInfo>();

			if (File.Exists(binPath))
			{
				var bytes = File.ReadAllBytes(binPath);
				using (var memoryStream = new MemoryStream(bytes))
				using (var reader = new BinaryReader(memoryStream))
				{
					while (memoryStream.Position < memoryStream.Length)
					{
						int paramID = reader.ReadInt32();
						var item = new WeaponInfo
						{
							attribute = reader.ReadInt32(),
							WeaponType = reader.ReadInt32(),
							ItemName = reader.ReadString(),
							SkillName1 = reader.ReadString(),
							SkillName2 = reader.ReadString(),
						};
						items.Add(paramID, item);
					}
					memoryStream.Dispose();
					memoryStream.Close();
					reader.Dispose();
					reader.Close();
				}
				//파일 읽기 종료
			}
			this.MasterBinList = items;
		}
		/// <summary>
		/// 어플리케이션 구동시 불러온 마스터 리스트를 기반으로 데이터를 검색해서 자동으로 세팅.
		/// </summary>
		/// <param name="MasterId"></param>
		/// <returns></returns>
		private WeaponInfo MasterInfoLoad(int MasterId, int paramId)
		{
			if (this.MasterBinList == null)
			{
				return new WeaponInfo//스킬 리스트에 직접 접근하지 못하므로 일단 스킬명은 String.Empty로 설정
{'fraction_non_alphanumeric': 0.13249102656137832, 'fraction_numerical': 0.015563531945441493, 'mean_word_length': 2.8065362334681385, 'pattern_counts': {'":': 0, '<': 117, '<?xml version=': 0, '>': 107, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5688520', 'n_tokens_mistral': 16657, 'n_tokens_neox': 13393, 'n_words': 2381}