Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Arcanum Enchanting v1.1.0 Korean localization for Korean client 한국어 로컬라이제이션
- //by [갓베]로무현 2015-09-21
- //사용법: plugins\zArcanum\Enchanting.cs 파일을 이 파일로 교체
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Windows.Input;
- using System.Windows.Navigation;
- using JetBrains.Annotations;
- using QuestTools;
- using QuestTools.Helpers;
- using Zeta.Game;
- using Zeta.Game.Internals;
- namespace Arcanum
- {
- public class Enchanting
- {
- static Enchanting()
- {
- OnStateChanged += (previous, current) =>
- {
- Logger.Log("State Changed from {0} to {1}", previous, current);
- };
- }
- public static UIElement EnchantButton { get { return UIElement.FromHash(0xBA58F7018A622DB3); } }
- public static UIElement EnchantStackPanel { get { return UIElement.FromHash(11989936962002177713); } }
- public static UIElement ConfirmEnchantDialog { get { return UIElement.FromHash(0x891D21408238D18E); } }
- public static UIElement ChoosePropertyText { get { return UIElement.FromHash(9844980432208557595); } }
- public static UIElement AlreadyEnchantedText { get { return UIElement.FromHash(8315348018061129442); } }
- public static UIElement RequiredMaterialsPanel { get { return UIElement.FromHash(10214243498069811485); } }
- public static UIElement AffixesDialog { get { return UIElement.FromHash(0x6C9DC02BBB83980F); } }
- public static UIElement CloseValidAffixesDialogButton { get { return UIElement.FromHash(0x78F39C99FC122C5C); } }
- public static UIElement OpenAffixesDialogButton { get { return UIElement.FromHash(0xAAEABCC414252CF6); } }
- public static UIElement ValidAffixesStackPanel { get { return UIElement.FromHash(2200502231488149432); } }
- public static Worker Worker = new Worker();
- public enum EnchantingState
- {
- /// <summary>
- /// Enchanting panel is not open
- /// </summary>
- NotEnchanting = 0,
- /// <summary>
- /// Box on enchanter panel doesnt have an item in it
- /// </summary>
- NoItemSelected,
- /// <summary>
- /// Item hasn't been enchanted before, select which property to replace
- /// </summary>
- SelectPropertyToEnchant,
- /// <summary>
- /// Ready to re-enchant a previously enchanted property
- /// </summary>
- EnchantProperty,
- /// <summary>
- /// Cant afford to click enchant button
- /// </summary>
- CantAffordToEnchant,
- /// <summary>
- /// New enchantment options are presented
- /// </summary>
- SelectNewEnchant,
- /// <summary>
- /// A New enchantment option is selected
- /// </summary>
- AcceptSelectedEnchant,
- }
- private static List<Enchantment> _validAffixes;
- public static List<Enchantment> ValidAffixes
- {
- get
- {
- UpdateValidAffixes();
- return _validAffixes;
- }
- private set { _validAffixes = value; }
- }
- private static int _previousItemsHash;
- private static void UpdateValidAffixes()
- {
- using (new MemoryHelper())
- {
- var result = new List<Enchantment>();
- if (!EnchantButton.IsValid || !EnchantButton.IsVisible || !EnchantStackPanel.IsValid || !EnchantStackPanel.IsVisible)
- return;
- if (EnchantButton.Text.ToLowerInvariant().Contains("place an item"))
- return;
- if (!AffixesDialog.IsVisible && !OpenAffixesDialogButton.IsVisible)
- return;
- if (!AffixesDialog.IsVisible)
- {
- OpenAffixesDialogButton.Click();
- Thread.Sleep(200);
- }
- if (!AffixesDialog.IsVisible)
- return;
- var items = ValidAffixesStackPanel.GetStackPanelItems();
- var itemsHash = StackPanelReader.GetStackPanelHashCode(items);
- if (itemsHash == _previousItemsHash)
- {
- Logger.Verbose("Skipping Affixes update due to same hash");
- return;
- }
- Logger.Verbose("Updating Valid Affixes");
- _previousItemsHash = itemsHash;
- items.ForEach(item =>
- {
- var text = CleanString(item.TextElement.Text);
- var enchant = ParseEnchantment(text);
- if (enchant.ItemProperty == ItemProperty.Unknown)
- {
- Logger.Log("Unknown ValidElement: {0}", text);
- return;
- }
- result.Add(enchant);
- });
- ValidAffixes = result;
- }
- }
- internal static void Enchant(List<Enchantment> desiredEnchants)
- {
- if (Worker.IsRunning || !desiredEnchants.Any())
- return;
- var startTime = DateTime.UtcNow;
- //Logger.Debug("Searching for: {0} >= {1}", desiredEnchant.Name, desiredEnchant.Value);
- UpdateValidAffixes();
- Worker.Start(() =>
- {
- using (new MemoryHelper())
- {
- Logger.Debug("State = {0}", State);
- if (UI.TimeoutEnabled && DateTime.UtcNow.Subtract(startTime).TotalSeconds > 600)
- {
- Logger.Log("Timeout Reached ({0}s)", 600);
- return true;
- }
- if (State != EnchantingState.EnchantProperty && State != EnchantingState.SelectNewEnchant)
- {
- switch (State)
- {
- case EnchantingState.NotEnchanting:
- Logger.Log("Enchanting Panel is not Visible");
- break;
- case EnchantingState.NoItemSelected:
- Logger.Log("You must put an item in the enchanting panel first");
- break;
- case EnchantingState.SelectPropertyToEnchant:
- Logger.Warn("First enchant is currently disabled for your safety");
- break;
- case EnchantingState.CantAffordToEnchant:
- Logger.Warn("You cannot afford to enchant any more");
- break;
- }
- return true;
- }
- if (State == EnchantingState.EnchantProperty)
- {
- var invalidEnchants = desiredEnchants.Where(e => !ValidAffixes.Contains(e)).ToList();
- if (invalidEnchants.Any())
- {
- invalidEnchants.ForEach(e => Logger.Log("The selected affix {0} is not valid for this item type", e.Name));
- return true;
- }
- //if (!ValidAffixes.Any(a => a.ItemProperty == desiredEnchant.ItemProperty && a.Variant == desiredEnchant.Variant ))
- //{
- // Logger.Log("The selected affix {0} is not valid for this item type", desiredEnchant);
- // return true;
- //}
- EnchantButton.Click();
- Thread.Sleep(500);
- return false;
- }
- return SelectNewProperty(desiredEnchants);
- }
- });
- }
- private static bool SelectNewProperty(List<Enchantment> desiredEnchants)
- {
- var panelChildren = UIElement.GetChildren(EnchantStackPanel).ToList();
- var matchFound = false;
- var upgradeFound = false;
- var currentEnchant = new Enchantment();
- Thread.Sleep(1500);
- Func<Enchantment, bool> isMatch = newEnchant =>
- {
- Logger.Verbose("Checking for Match {0} {1} against {2} desired enchants",
- newEnchant.Name,
- newEnchant.Value,
- desiredEnchants.Count);
- foreach (var desiredEnchant in desiredEnchants)
- {
- if (desiredEnchant.Equals(newEnchant))
- {
- Logger.Verbose(">> {0} {1} >= {2} {3}",
- newEnchant.Name,
- newEnchant.Value,
- desiredEnchant.Name,
- desiredEnchant.Value);
- return newEnchant.Value >= desiredEnchant.Value;
- }
- }
- Logger.Verbose(">> {0} {1} not a match", newEnchant.Name, newEnchant.Value);
- return false;
- };
- Func<Enchantment, bool> isUpgrade = newEnchant =>
- {
- Logger.Verbose("Checking for Upgrade on existing enchant: {0} {1}",
- currentEnchant.Name,
- currentEnchant.Value);
- var isNewEnchantDesired = desiredEnchants.Contains(newEnchant);
- var isCurrentEnchantDesired = desiredEnchants.Contains(currentEnchant);
- // Allow upgrade if current enchant is not what we're looking for and new enchant is
- if (!isCurrentEnchantDesired && isNewEnchantDesired)
- {
- Logger.Verbose(">> {0} {1} is an upgrade because current enchant ({2}) is not what we're looking for",
- newEnchant.Name,
- newEnchant.Value,
- currentEnchant.Name);
- return true;
- }
- // Allow upgrade if current enchant is the same (ItemProperty and Variant) as new enchant and new enchant is better.
- if (isNewEnchantDesired && newEnchant.Equals(currentEnchant))
- {
- Logger.Verbose(">> {0} {1} >= {2} {3}",
- newEnchant.Name,
- newEnchant.Value,
- currentEnchant.Name,
- currentEnchant.Value);
- return newEnchant.Value > currentEnchant.Value;
- }
- // Allow cross-type upgrades for variants of the same ItemPropery E.g. Fire Damage 12% > Poison Damage 10%
- if (newEnchant.ItemProperty == currentEnchant.ItemProperty && currentEnchant.ItemProperty == ItemProperty.BaseDamage)
- {
- Logger.Verbose(">> {0} {1} >= {2} {3}",
- newEnchant.Name,
- newEnchant.Value,
- currentEnchant.Name,
- currentEnchant.Value);
- return newEnchant.Value > currentEnchant.Value;
- }
- Logger.Verbose(">> {0} {1} not an upgrade", newEnchant.Name, newEnchant.Value);
- return false;
- };
- var items = EnchantStackPanel.GetStackPanelItems();
- if (!items.Any())
- {
- Logger.Debug("No Enchant UIElements were found");
- return false;
- }
- var upgradeElement = panelChildren[0];
- var matchElement = panelChildren[0];
- foreach (var item in items)
- {
- var text = CleanString(item.TextElement.Text);
- var enchant = ParseEnchantment(text);
- if (items.ElementAt(0) == item)
- {
- currentEnchant = enchant;
- Logger.Debug("Existing Enchant: {0} ({1}) {2}", enchant.ItemProperty, enchant.Value, enchant.Variant);
- }
- else if (isMatch(enchant))
- {
- Logger.Warn("Found Match!: {0} ({1}) {2}", enchant.ItemProperty, enchant.Value, enchant.Variant);
- matchElement = item.ItemElement; ;
- matchFound = true;
- }
- else if (isUpgrade(enchant))
- {
- Logger.Warn("Found Upgrade!: {0} ({1}) {2}, still searching though...", enchant.ItemProperty, enchant.Value, enchant.Variant);
- upgradeElement = item.ItemElement;
- upgradeFound = true;
- }
- else
- {
- Logger.Log("Found: {0} ({1}) {2}", enchant.ItemProperty, enchant.Value, enchant.Variant);
- }
- if (enchant.ItemProperty == ItemProperty.Unknown)
- Logger.Log("Failed to understand string: {0}", text);
- Thread.Sleep(50);
- }
- if (matchFound)
- {
- matchElement.Click();
- }
- else if (upgradeFound)
- {
- upgradeElement.Click();
- }
- else
- {
- panelChildren[0].Click();
- }
- Thread.Sleep(50);
- if (EnchantButton.IsEnabled)
- {
- EnchantButton.Click();
- Thread.Sleep(50);
- }
- if (ConfirmEnchantDialog != null && ConfirmEnchantDialog.IsValid && ConfirmEnchantDialog.IsVisible)
- ConfirmEnchantDialog.Click();
- Thread.Sleep(500);
- return matchFound;
- }
- internal static Enchantment ParseEnchantment(string input)
- {
- var e = new Enchantment();
- if (string.IsNullOrEmpty(input))
- return e;
- // http://regexhero.net/tester/
- var regex = new Regex(@"(?<value>[\d\.,]+)(?<=[^\.])|(?<1>생명력)|(?<2>방어도)|(?<3>극대화 확률)|(?<4>극대화 피해)|(?<5>.*)로 주는 피해|(?<6>소모한 공력 1당 생명력)|(?<7>민첩)|(?<8>힘)|(?<9>지능)|(?<10>활력)|(?<11>광역 피해)|(?<12>재사용 대기시간)|(?<13>자원 소모량)|(?<14>Durability)|(?<15>물리 저항)|(?<16>냉기 저항)|(?<17>화염 저항)|(?<18>번개 저항)|(?<19>비전 저항)|(?<20>독 저항)|(?<21>적에게서 얻는 금화)|(?<22>공격자에게 적중 시)|(?<23>획득 반경)|(?<24>적중 시 오한)|(?<25>내구도 감소 무시)|(?<26>생명의 구슬과 물약으로)|(?<27>요구 레벨)|(?<28>이동 속도)|(?<29>모든 원소)|(?<30>적을 처치하고 얻는)|(?<31>적중 시 이동 불가)|(?<32>적중 시 실명)|(?<33>제어 방해 효과의 지속시간)|(?<34>냉기 기술로)|(?<35>화염 기술로)|(?<36>신성 기술로)|(?<37>번개 기술로)|(?<38>독 기술로)|(?<39>물리 기술로)|(?<40>진노 생성량)|(?<41>공격 속도)|(?<42>적중 시 생명력)|(?<43>정예에게 받는 피해)|(?<44>확률로 출혈)|(?<45>증오 회복량)|(?<46>홈)|(?<47>화염 무기 공격력|비전 무기 공격력|독 무기 공격력|번개 무기 공격력|냉기 무기 공격력|신성 무기 공격력|무기 공격력)(?<!\]%|%)(?!\sper|\.)|(?<48>소모한 진노 1당 생명력)|(?<49>최대 진노)|(?<50>소모한 분노 1당 생명력)|(?<51>공력 회복량)|(?<52>정예에게 주는 피해)|(?<53>처치 시 생명력)|(?<54>최대 마나)|(?<55>최대 비전력)|(?<56>근접 공격으로 받는)|(?<57>원거리 공격으로 받는)|(?<58>최대 공력)|(?<59>최대 분노)|(?<60>방패막기 확률)|(?<61>적중 시 공포)|(?<62>적중 시 기절)|(?<63>적중 시 빙결)|(?<64>적중 시 감속)|(?<65>적중 시 밀치기)|(?<66>초당 생명력)|(?<67>최대 절제)|(?<68>극대화 적중 시 비전력)|(?<69>비전 기술로)|(?<70>마나 회복량)|(?<71>(?!\sper|\.)피해)");
- var groupMatches = regex.GroupMatches(input);
- if (!groupMatches.Strings.Any())
- return e;
- e.ItemProperty = (ItemProperty)groupMatches.Strings.First().GroupIndex;
- if (groupMatches.Numbers.Any())
- {
- e.Maximum = groupMatches.Numbers.Max(i => i.NumberValue);
- e.Minimum = groupMatches.Numbers.Min(i => i.NumberValue);
- }
- if (e.ItemProperty == ItemProperty.SkillDamage || e.ItemProperty == ItemProperty.BaseDamage)
- {
- e.Variant = CleanString(groupMatches.Strings.First().StringValue);
- }
- e.Value = e.Maximum;
- e.Original = input;
- return e;
- }
- private static EnchantingState _lastState = EnchantingState.NotEnchanting;
- public static EnchantingState State
- {
- get
- {
- var state = EnchantingState.NotEnchanting;
- using(new MemoryHelper())
- {
- if (!ZetaDia.IsInGame || ZetaDia.Me == null || !ZetaDia.Me.IsValid || !ZetaDia.IsInTown)
- state = EnchantingState.NotEnchanting;
- else if (!EnchantButton.IsValid || !EnchantButton.IsVisible || !EnchantStackPanel.IsValid || !EnchantStackPanel.IsVisible)
- state = EnchantingState.NotEnchanting;
- else if (EnchantButton.Text.ToLowerInvariant().Contains("아이템을 올려놓으십시오"))
- state = EnchantingState.NoItemSelected;
- else if (EnchantButton.Text.ToLowerInvariant().Contains("교체할 속성을 선택하십시오"))
- state = EnchantingState.SelectPropertyToEnchant;
- else if (EnchantButton.Text.ToLowerInvariant().Contains("속성 선택"))
- state = EnchantingState.SelectNewEnchant;
- else if (EnchantButton.Text.ToLowerInvariant().Contains("속성 교체"))
- {
- if (RequiredMaterialsPanel.IsValid && RequiredMaterialsPanel.IsVisible && EnchantButton.IsValid && !EnchantButton.IsEnabled)
- state = EnchantingState.CantAffordToEnchant;
- else
- state = EnchantingState.EnchantProperty;
- }
- }
- if (_lastState != state)
- {
- OnStateChanged(_lastState, state);
- }
- _lastState = state;
- return state;
- }
- }
- public delegate void LoaderEvent(EnchantingState previous, EnchantingState current);
- public static event LoaderEvent OnStateChanged = (p,v) => { };
- /// <summary>
- /// Strips out a name from color encoded UI string e.g.
- /// {c:ff6969ff}Corrupted Angel{/c}
- /// </summary>
- public static string CleanString(string s)
- {
- try
- {
- return Regex.Replace(s, "{([^}]*)}", "").Trim();
- }
- catch (Exception ex)
- {
- Logger.Debug("Exception in CleanString {0}", ex);
- }
- return s.Trim();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement