├── .vs └── Maple │ └── v16 │ ├── .suo │ └── Server │ └── sqlite3 │ ├── db.lock │ └── storage.ide ├── Maple.sln ├── Maple ├── App.config ├── App.xaml ├── App.xaml.cs ├── Controls │ └── LabeledControl │ │ └── LabeledControl.cs ├── Data │ ├── CharacterData.cs │ ├── GameData.cs │ ├── ImageFinder.cs │ ├── Imaging.cs │ ├── Input.cs │ ├── JumpData.cs │ ├── MapData.cs │ ├── MapleMath.cs │ ├── MapleSerialPort.cs │ ├── MobData.cs │ └── SkillData.cs ├── Images │ ├── BlueEspressoMachineLeft.png │ ├── BlueEspressoMachineRight.png │ ├── BlueRaspberryJellyJuiceLeft.png │ ├── BlueRaspberryJellyJuiceRight.png │ ├── ChangeChannel.png │ ├── CharacterSelectionCharacterSlot.png │ ├── ClaimReward.png │ ├── ContentGuide.png │ ├── DemonAvengerName.png │ ├── FullHealthBar.png │ ├── HP.png │ ├── HealthBarDropping.png │ ├── HealthBarEmpty.png │ ├── LeftHealthBar.png │ ├── OtherPlayerMiniMap.png │ ├── OverheadQuest.png │ ├── PlayerMiniMap.png │ ├── RebootServer.png │ ├── RebootServerChannelSelect.png │ ├── Rune.png │ ├── RuneMiniMap.png │ ├── TheNextLegendTitle.png │ ├── badguy1.png │ ├── map1.png │ ├── runetest1.png │ ├── runetest2.png │ ├── runetest3.png │ ├── runetest4.png │ └── runetest5.png ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── Maple.csproj ├── Models │ └── ModelBase.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── ViewModels │ ├── GamePlayerViewModel.cs │ ├── JobEditViewModel.cs │ ├── JobsWindowViewModel.cs │ ├── MainWindowViewModel.cs │ ├── MapCreatorViewModel.cs │ ├── SkillEditViewModel.cs │ └── ViewModelBase.cs ├── Windows │ ├── GamePlayer.xaml │ ├── GamePlayer.xaml.cs │ ├── JobEdit.xaml │ ├── JobEdit.xaml.cs │ ├── JobsWindow.xaml │ ├── JobsWindow.xaml.cs │ ├── MapCreator.xaml │ ├── MapCreator.xaml.cs │ ├── SkillEdit.xaml │ ├── SkillEdit.xaml.cs │ ├── StatisticsViewer.xaml │ └── StatisticsViewer.xaml.cs ├── bin │ └── Debug │ │ ├── Maple.exe │ │ ├── Maple.exe.config │ │ └── Maple.pdb ├── obj │ └── Debug │ │ ├── App.g.cs │ │ ├── App.g.i.cs │ │ ├── DesignTimeResolveAssemblyReferences.cache │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ ├── MainWindow.baml │ │ ├── MainWindow.g.cs │ │ ├── MainWindow.g.i.cs │ │ ├── Maple.Properties.Resources.resources │ │ ├── Maple.csproj.CopyComplete │ │ ├── Maple.csproj.FileListAbsolute.txt │ │ ├── Maple.csproj.GenerateResource.cache │ │ ├── Maple.csprojAssemblyReference.cache │ │ ├── Maple.exe │ │ ├── Maple.g.resources │ │ ├── Maple.pdb │ │ ├── Maple_Content.g.i.cs │ │ ├── Maple_MarkupCompile.cache │ │ ├── Maple_MarkupCompile.i.cache │ │ ├── Maple_MarkupCompile.lref │ │ └── Windows │ │ ├── MapCreator.baml │ │ ├── MapCreator.g.cs │ │ ├── MapCreator.g.i.cs │ │ ├── StatisticsViewer.baml │ │ ├── StatisticsViewer.g.cs │ │ └── StatisticsViewer.g.i.cs └── packages.config ├── MaplestoryBotArduinoKeyboard ├── MaplestoryBotArduinoKeyboard.ino └── Pro_micro_build.bat.txt ├── MaplestoryBotArduinoMaster └── MaplestoryBotArduinoMaster.ino ├── MaplestoryBotArduinoMouse └── MaplestoryBotArduinoMouse.ino └── README.md /.vs/Maple/v16/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/.vs/Maple/v16/.suo -------------------------------------------------------------------------------- /.vs/Maple/v16/Server/sqlite3/db.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/.vs/Maple/v16/Server/sqlite3/db.lock -------------------------------------------------------------------------------- /.vs/Maple/v16/Server/sqlite3/storage.ide: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/.vs/Maple/v16/Server/sqlite3/storage.ide -------------------------------------------------------------------------------- /Maple.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29806.167 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Maple", "Maple\Maple.csproj", "{4323BFC3-33BD-4478-A364-FAAC2BE09F74}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {4323BFC3-33BD-4478-A364-FAAC2BE09F74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {4323BFC3-33BD-4478-A364-FAAC2BE09F74}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {4323BFC3-33BD-4478-A364-FAAC2BE09F74}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {4323BFC3-33BD-4478-A364-FAAC2BE09F74}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {ACDE779A-102C-4B7F-AF93-3C89800D6FEF} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Maple/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Maple/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Maple/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace Maple 10 | { 11 | /// 12 | /// Interaction logic for App.xaml 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Maple/Controls/LabeledControl/LabeledControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | 9 | namespace Maple.Controls.LabeledControl 10 | { 11 | public class LabeledControl : HeaderedContentControl 12 | { 13 | static LabeledControl() 14 | { 15 | DefaultStyleKeyProperty.OverrideMetadata(typeof(LabeledControl), new FrameworkPropertyMetadata(typeof(LabeledControl))); 16 | } 17 | 18 | public double LabelWidth 19 | { 20 | get { return (double)GetValue(LabelWidthProperty); } 21 | set { SetValue(LabelWidthProperty, value); } 22 | } 23 | 24 | public static readonly DependencyProperty LabelWidthProperty = 25 | DependencyProperty.Register("LabelWidth", typeof(double), typeof(LabeledControl), new PropertyMetadata(Double.NaN)); 26 | 27 | public double LabelHeight 28 | { 29 | get { return (double)GetValue(LabelHeightProperty); } 30 | set { SetValue(LabelHeightProperty, value); } 31 | } 32 | 33 | public static readonly DependencyProperty LabelHeightProperty = 34 | DependencyProperty.Register("LabelHeight", typeof(double), typeof(LabeledControl), new PropertyMetadata(Double.NaN)); 35 | 36 | public Dock LabelDock 37 | { 38 | get { return (Dock)GetValue(LabelDockProperty); } 39 | set 40 | { 41 | switch (value) 42 | { 43 | case Dock.Bottom: 44 | break; 45 | case Dock.Left: 46 | break; 47 | case Dock.Right: 48 | break; 49 | case Dock.Top: 50 | break; 51 | } 52 | SetValue(LabelDockProperty, value); 53 | } 54 | } 55 | 56 | public static readonly DependencyProperty LabelDockProperty = 57 | DependencyProperty.Register("LabelDock", typeof(Dock), typeof(LabeledControl), new PropertyMetadata(Dock.Left)); 58 | 59 | public TextAlignment LabelTextAlignment 60 | { 61 | get { return (TextAlignment)GetValue(LabelTextAlignmentProperty); } 62 | set { SetValue(LabelTextAlignmentProperty, value); } 63 | } 64 | 65 | public static readonly DependencyProperty LabelTextAlignmentProperty = 66 | DependencyProperty.Register("LabelTextAlignment", typeof(TextAlignment), typeof(LabeledControl), new PropertyMetadata(TextAlignment.Left)); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Maple/Data/CharacterData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace Maple.Data 9 | { 10 | public enum Jobs 11 | { 12 | FirePoisonMage, 13 | AngelicBuster, 14 | Bowmaster, 15 | WildHunter, 16 | Paladin, 17 | Hero, 18 | Shadower, 19 | Zero, 20 | Evan, 21 | Buccaneer, 22 | Bishop, 23 | BeastTamer, 24 | Kinesis, 25 | Luminous, 26 | NightWalker, 27 | DemonSlayer, 28 | IceLightningMage, 29 | Blaster, 30 | DemonAvenger, 31 | BattleMage, 32 | Shade, 33 | Illium, 34 | Ark, 35 | Pathfinder, 36 | Kaiser, 37 | Hayato, 38 | Aran, 39 | Phantom, 40 | BlazeWizard, 41 | DarkKnight, 42 | Mechanic, 43 | NightLord, 44 | Corsair, 45 | Cannoneer, 46 | Marksman, 47 | Mercedes, 48 | DualBlade, 49 | WindArcher, 50 | DawnWarrior, 51 | Hoyoung, 52 | Mihile, 53 | Cadena, 54 | ThunderBreaker, 55 | Jett, 56 | Xenon, 57 | Adele, 58 | Kain, 59 | Kanna 60 | } 61 | 62 | class CharacterData 63 | { 64 | public string CharacterName { get; set; } 65 | public Jobs CharacterJob { get; set; } 66 | int Level { get; set; } 67 | public JumpData JumpDataData { get; set; } 68 | public List SkillDataList { get; set; } 69 | public int CharacterSelectionLocation { get; set; } 70 | 71 | public bool TryToUseSkill() 72 | { 73 | var curSkill = SkillDataList.OrderBy(x => x.NextUseTime).First(); 74 | if (curSkill.NextUseTime < DateTime.Now) 75 | { 76 | curSkill.UseSkill(); 77 | return true; 78 | } 79 | return false; 80 | } 81 | 82 | public CharacterData() 83 | { 84 | SkillDataList = new List(); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Maple/Data/Input.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.Configuration; 5 | using System.IO.Ports; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | 11 | namespace Maple.Data 12 | { 13 | public class Input 14 | { 15 | public enum SpecialCharacters 16 | { 17 | KEY_LEFT_CTRL = 128, 18 | KEY_LEFT_SHIFT = 129, 19 | KEY_LEFT_ALT = 130, 20 | KEY_LEFT_GUI = 131, 21 | KEY_RIGHT_CTRL = 132, 22 | KEY_RIGHT_SHIFT = 133, 23 | KEY_RIGHT_ALT = 134, 24 | KEY_RIGHT_GUI = 135, 25 | KEY_UP_ARROW = 218, 26 | KEY_DOWN_ARROW = 217, 27 | KEY_LEFT_ARROW = 216, 28 | KEY_RIGHT_ARROW = 215, 29 | KEY_BACKSPACE = 178, 30 | KEY_TAB = 179 , 31 | KEY_RETURN = 176 , 32 | KEY_ESC = 177 , 33 | KEY_INSERT = 209 , 34 | KEY_DELETE = 212 , 35 | KEY_PAGE_UP = 211 , 36 | KEY_PAGE_DOWN = 214 , 37 | KEY_HOME = 210, 38 | KEY_END = 213, 39 | KEY_CAPS_LOCK = 193, 40 | KEY_F1 = 194, 41 | KEY_F2 = 195, 42 | KEY_F3 = 196, 43 | KEY_F4 = 197, 44 | KEY_F5 = 198, 45 | KEY_F6 = 199, 46 | KEY_F7 = 200, 47 | KEY_F8 = 201, 48 | KEY_F9 = 202, 49 | KEY_F10 = 203, 50 | KEY_F11 = 204, 51 | KEY_F12 = 205, 52 | } 53 | 54 | public static MapleSerialPort MasterArduinoData; 55 | public static MapleSerialPort KeyboardArduinoData; 56 | public static MapleSerialPort MouseArduinoData; 57 | 58 | public static ConcurrentDictionary ActiveCharInput = new ConcurrentDictionary(); 59 | public static ConcurrentDictionary ActiveSpecialCharInput = new ConcurrentDictionary(); 60 | public static bool NewInputEnabled; 61 | 62 | public static void StopAllKeyboardInput() 63 | { 64 | List charsToRemove = ActiveCharInput.Keys.ToList(); 65 | List specialCharsToRemove = ActiveSpecialCharInput.Keys.ToList(); 66 | foreach (var curChar in charsToRemove) 67 | { 68 | StopInput(curChar); 69 | } 70 | foreach (var curSpecialChar in specialCharsToRemove) 71 | { 72 | StopInput(curSpecialChar); 73 | } 74 | } 75 | 76 | public static void StartInput(char c) 77 | { 78 | if (!NewInputEnabled) 79 | { 80 | return; 81 | } 82 | ActiveCharInput[c] = DateTime.Now; 83 | int asciiVal = (int)c; 84 | string asciiValString = asciiVal.ToString().PadLeft(3, '0'); 85 | MasterArduinoData.SendData($"KEYDOWN{asciiValString}"); 86 | } 87 | 88 | public static void StartInput(SpecialCharacters specialCharacter) 89 | { 90 | if (!NewInputEnabled) 91 | { 92 | return; 93 | } 94 | ActiveSpecialCharInput[specialCharacter] = DateTime.Now; 95 | int asciiVal = (int)specialCharacter; 96 | string asciiValString = asciiVal.ToString().PadLeft(3, '0'); 97 | MasterArduinoData.SendData($"KEYDOWN{asciiValString}"); 98 | } 99 | 100 | public static void StopInput(char c) 101 | { 102 | if (!ActiveCharInput.TryRemove(c, out DateTime inputDateTime)) 103 | { 104 | return; 105 | } 106 | int asciiVal = (int)c; 107 | string asciiValString = asciiVal.ToString().PadLeft(3, '0'); 108 | MasterArduinoData.SendData($"KEYLIFT{asciiValString}"); 109 | } 110 | 111 | public static void StopInput(SpecialCharacters specialCharacter) 112 | { 113 | if (!ActiveSpecialCharInput.TryRemove(specialCharacter, out DateTime inputDateTime)) 114 | { 115 | return; 116 | } 117 | int asciiVal = (int)specialCharacter; 118 | string asciiValString = asciiVal.ToString().PadLeft(3, '0'); 119 | MasterArduinoData.SendData($"KEYLIFT{asciiValString}"); 120 | } 121 | 122 | private static void MoveMouse(Vector2 location) 123 | { 124 | // MV00000000 125 | string movXString = location.X.ToString().PadLeft(4, '0'); 126 | string movYString = location.Y.ToString().PadLeft(4, '0'); 127 | MasterArduinoData.SendData($"MV{movXString}{movYString}"); 128 | _mouseLocation = new Vector2(Math.Max(_mouseLocation.X + location.X, 0), Math.Max(_mouseLocation.Y + location.Y, 0)); 129 | } 130 | 131 | public static void SetMouseLocation(Vector2 location) 132 | { 133 | Random rand = new Random(); 134 | /*int sleepAmount = 1; 135 | int randX; 136 | int randY; 137 | int numPolys = rand.Next(1, 4);*/ 138 | if (_mouseLocation.X == location.X) 139 | { 140 | MoveMouse(new Vector2(rand.Next(3, 10), rand.Next(1, 5))); 141 | } 142 | List locations = new List() { location, _mouseLocation }; 143 | /*for (int i = 0; i < numPolys; i++) 144 | { 145 | randX = location.X - _mouseLocation.X; 146 | randY = location.Y - _mouseLocation.Y; 147 | int moveAmountX = rand.Next(Math.Min(randX, 0), Math.Max(randX + 1, 0)); 148 | int moveAmountY = rand.Next(Math.Min(randY, 0), Math.Max(randY + 1, 0)); 149 | locations.Add(new Vector2(moveAmountX, moveAmountY)); 150 | }*/ 151 | var moveLocations = MapleMath.PolynomialLeastSquares(locations.OrderBy(x => x.X).ToList()); 152 | int originalIterator = 0; 153 | int iteratorChangeAmount = 1; 154 | int maxVal = moveLocations.Count; 155 | if (_mouseLocation.X > location.X) 156 | { 157 | originalIterator = moveLocations.Count - 1; 158 | iteratorChangeAmount = -1; 159 | maxVal = -1; 160 | } 161 | for (int i = originalIterator; i != maxVal; i += iteratorChangeAmount) 162 | { 163 | Vector2 curLocation = moveLocations[i]; 164 | MoveMouse(new Vector2(curLocation.X - _mouseLocation.X, curLocation.Y - _mouseLocation.Y)); 165 | } 166 | /*while (_mouseLocation.X != location.X || _mouseLocation.Y != location.Y) 167 | { 168 | 169 | sleepAmount = rand.Next(5, 15); 170 | MoveMouse(new Vector2(moveAmountX, moveAmountY)); 171 | Thread.Sleep(sleepAmount); 172 | }*/ 173 | //MoveMouse(new Vector2(location.X, location.Y)); 174 | } 175 | 176 | private static Vector2 _mouseLocation; 177 | 178 | 179 | public static void ClickMouse() 180 | { 181 | MasterArduinoData.SendData($"MOUSELCLCK"); 182 | } 183 | 184 | public static void RightClickMouse() 185 | { 186 | MasterArduinoData.SendData($"MOUSERCLCK"); 187 | } 188 | 189 | public static void ReleaseMouse() 190 | { 191 | MasterArduinoData.SendData($"MOUSELRLAX"); 192 | } 193 | 194 | public static void RightReleaseMouse() 195 | { 196 | MasterArduinoData.SendData($"MOUSERRLAX"); 197 | } 198 | 199 | public static void ResetMouse() 200 | { 201 | /*for (int i = 0; i < 10; i++) 202 | { 203 | Input.MoveMouse(new Vector2(10, 100)); 204 | }*/ 205 | _mouseLocation = new Vector2(500, 500); 206 | Input.MoveMouse(new Vector2(10, 10)); 207 | for (int i = 0; i < 50; i++) 208 | { 209 | Input.MoveMouse(new Vector2(-100, 0)); 210 | } 211 | Input.MoveMouse(new Vector2(10, 0)); 212 | for (int i = 0; i < 50; i++) 213 | { 214 | Input.MoveMouse(new Vector2(0, -100)); 215 | } 216 | for (int i = 0; i < 50; i++) 217 | { 218 | Input.MoveMouse(new Vector2(-100, 0)); 219 | } 220 | Input.MoveMouse(new Vector2(-20, 0)); 221 | _mouseLocation = new Vector2(0, 0); 222 | } 223 | 224 | public static void InitializeInputs() 225 | { 226 | Input.KeyboardArduinoData = new MapleSerialPort("Keyboard", ConfigurationManager.AppSettings["ArduinoKeyboardComNumber"]); 227 | Input.MasterArduinoData = new MapleSerialPort("Master", ConfigurationManager.AppSettings["ArduinoMasterComNumber"]); 228 | Input.MouseArduinoData = new MapleSerialPort("Mouse", ConfigurationManager.AppSettings["ArduinoMouseComNumber"]); 229 | ResetMouse(); 230 | ClickMouse(); 231 | Thread.Sleep(11); 232 | ReleaseMouse(); 233 | } 234 | 235 | /*public static void DoubleClickMouse() 236 | { 237 | ArduinoPortData.Write($"MDCLCK"); 238 | } 239 | 240 | private static void DisconnectFromArduino() 241 | { 242 | //IsConnected = false; 243 | ArduinoPortData.Write("#STOP\n"); 244 | ArduinoPortData.Close(); 245 | }*/ 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /Maple/Data/JumpData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace Maple.Data 9 | { 10 | public enum JumpTypes 11 | { 12 | //ArrowUpJumpJump, 13 | ArrowJumpUpUp, 14 | ArrowJump, 15 | ArrowJumpJump, 16 | ArrowFlashJump, 17 | JumpDown 18 | } 19 | 20 | public class DelaysAndEquationCoefficients 21 | { 22 | public List MillisecondDelays { get; set; } 23 | public List EquationCoefficients { get; set; } 24 | 25 | public double MaxX; 26 | 27 | public double MaxY; 28 | 29 | public List JumpDataPoints { get; set; } 30 | 31 | public double GetYValueFromXValue(double xValue) 32 | { 33 | double curYValue = EquationCoefficients[EquationCoefficients.Count - 1]; 34 | int curNumXs = 1; 35 | for (int i = EquationCoefficients.Count - 2; i >= 0; i--) 36 | //for (int i = 0; i < EquationCoefficients.Count - 1; i++) 37 | { 38 | double curVal = xValue; 39 | for (int j = 1; j < curNumXs; j++) 40 | { 41 | curVal = curVal * xValue; 42 | } 43 | curVal = curVal * EquationCoefficients[i]; 44 | curYValue += curVal; 45 | curNumXs++; 46 | } 47 | return curYValue; 48 | } 49 | 50 | public List EnumerateValues() 51 | { 52 | List returnData = new List(); 53 | for (int i = 0; i < MaxX; i++) 54 | { 55 | returnData.Add(new Vector2(i, GetYValueFromXValue(i))); 56 | } 57 | return returnData; 58 | } 59 | 60 | public DelaysAndEquationCoefficients(List millisecondDelays, List equationCoefficients, double maxX, double maxY, List jumpDataPoints) 61 | { 62 | MillisecondDelays = millisecondDelays; 63 | EquationCoefficients = equationCoefficients; 64 | MaxX = maxX; 65 | MaxY = maxY; 66 | JumpDataPoints = jumpDataPoints; 67 | } 68 | } 69 | 70 | public class JumpInformation 71 | { 72 | public JumpTypes JumpType { get; set; } 73 | 74 | public List MillisecondDelaysToEquationCoefficients { get; set; } 75 | 76 | public JumpInformation(JumpTypes jumpType) 77 | { 78 | JumpType = jumpType; 79 | MillisecondDelaysToEquationCoefficients = new List(); 80 | } 81 | 82 | public void AddToDelaysAndEquationCoefficients(Tuple, List, double, double, List> newData) 83 | { 84 | MillisecondDelaysToEquationCoefficients.Add(new DelaysAndEquationCoefficients(newData.Item1, newData.Item2, newData.Item3, newData.Item4, newData.Item5)); 85 | } 86 | } 87 | 88 | public class JumpData 89 | { 90 | public static Dictionary JumpTypesToNumberOfPauses = new Dictionary() 91 | { 92 | { JumpTypes.ArrowJumpUpUp, 5 }, 93 | { JumpTypes.ArrowJump, 1 }, 94 | { JumpTypes.ArrowJumpJump, 3 }, 95 | { JumpTypes.ArrowFlashJump, 1 }, 96 | { JumpTypes.JumpDown, 3 } 97 | }; 98 | 99 | public static List MilliDelays = new List() { 20, 50, 100 }; 100 | // int is intercharacter delay 101 | //public Dictionary>, List> JumpTypeAndDelayToEquationCoefficients { get; set; } 102 | public List JumpInformationDataList; 103 | 104 | 105 | public JumpData() 106 | { 107 | JumpInformationDataList = new List(); 108 | //JumpTypeAndDelayToEquationCoefficients = new Dictionary>, List>(); 109 | } 110 | 111 | private enum GenerateEquationCoefficientsStatuses 112 | { 113 | Unstarted = 5, 114 | FindingInitialYMovement = 1, 115 | FindingYMovementStop = 2, 116 | Finished = 3 117 | } 118 | 119 | public static JumpData GenerateJumpData() 120 | { 121 | JumpData jumpDataData = new JumpData(); 122 | foreach (var curJumpType in (JumpTypes[]) Enum.GetValues(typeof(JumpTypes))) 123 | { 124 | jumpDataData.JumpInformationDataList.Add(new JumpInformation(curJumpType)); 125 | List, List, double, double, List>> equationCoefficientData = GenerateEquationCoefficientsForJumpType(curJumpType); 126 | foreach (var curEquationCoefficientData in equationCoefficientData) 127 | { 128 | jumpDataData.JumpInformationDataList.Last().AddToDelaysAndEquationCoefficients(curEquationCoefficientData); 129 | var x = jumpDataData.JumpInformationDataList.Last().MillisecondDelaysToEquationCoefficients.Last().EnumerateValues(); 130 | //jumpDataData.JumpTypeAndDelayToEquationCoefficients[new Tuple>(curJumpType, curEquationCoefficientData.Item1)] = curEquationCoefficientData.Item2; 131 | } 132 | } 133 | return jumpDataData; 134 | } 135 | 136 | private static bool IncrementIterators(ref List iterators, int max) 137 | { 138 | iterators.Reverse(); 139 | bool ableToIncrement = false; 140 | for (int i = 0; i < iterators.Count; i++) 141 | { 142 | if (iterators[i] == max) 143 | { 144 | continue; 145 | } 146 | for (int j = 0; j < i; j++) 147 | { 148 | iterators[j] = 0; 149 | } 150 | iterators[i]++; 151 | ableToIncrement = true; 152 | break; 153 | } 154 | iterators.Reverse(); 155 | return ableToIncrement; 156 | } 157 | 158 | private static List, List, double, double, List>> GenerateEquationCoefficientsForJumpType(JumpTypes jumpType) 159 | { 160 | int numberOfDelays = JumpTypesToNumberOfPauses[jumpType]; 161 | List curDelays = new List(); 162 | var returnData = new List, List, double, double, List>>(); 163 | double maxX, maxY; 164 | List jumpDataPoints; 165 | for (int i = 0; i < numberOfDelays; i++) 166 | { 167 | curDelays.Add(0); 168 | } 169 | do 170 | { 171 | var millisecondDelays = curDelays.Select(x => { return MilliDelays[x]; }).ToList(); 172 | Console.WriteLine($"Generating equation coefficients for jump type [{jumpType.ToString()}] and iterators [{string.Join(", ", curDelays)}]"); 173 | var equationCoefficients = GenerateEquationCoefficients(jumpType, millisecondDelays, out maxX, out maxY, out jumpDataPoints); 174 | if (equationCoefficients == null || equationCoefficients.Count == 0) 175 | { 176 | continue; 177 | } 178 | returnData.Add(new Tuple, List, double, double, List>(millisecondDelays, equationCoefficients, maxX, maxY, jumpDataPoints)); 179 | 180 | } 181 | while (IncrementIterators(ref curDelays, MilliDelays.Count - 1)); 182 | return returnData; 183 | } 184 | 185 | public static void TryToJump(JumpTypes jumpType, List millisecondDelays) 186 | { 187 | switch (jumpType) 188 | { 189 | case JumpTypes.ArrowFlashJump: 190 | Input.StartInput('e'); 191 | Thread.Sleep(millisecondDelays[0]); 192 | Input.StopInput('e'); 193 | break; 194 | case JumpTypes.ArrowJump: 195 | Input.StartInput(Input.SpecialCharacters.KEY_LEFT_ALT); 196 | Thread.Sleep(millisecondDelays[0]); 197 | Input.StopInput(Input.SpecialCharacters.KEY_LEFT_ALT); 198 | break; 199 | case JumpTypes.ArrowJumpJump: 200 | 201 | Input.StartInput(Input.SpecialCharacters.KEY_LEFT_ALT); 202 | Thread.Sleep(millisecondDelays[0]); 203 | Input.StopInput(Input.SpecialCharacters.KEY_LEFT_ALT); 204 | Thread.Sleep(millisecondDelays[1]); 205 | Input.StartInput(Input.SpecialCharacters.KEY_LEFT_ALT); 206 | Thread.Sleep(millisecondDelays[2]); 207 | Input.StopInput(Input.SpecialCharacters.KEY_LEFT_ALT); 208 | break; 209 | case JumpTypes.ArrowJumpUpUp: 210 | Input.StartInput(Input.SpecialCharacters.KEY_LEFT_ALT); 211 | Thread.Sleep(millisecondDelays[0]); 212 | Input.StartInput(Input.SpecialCharacters.KEY_UP_ARROW); 213 | Thread.Sleep(millisecondDelays[1]); 214 | Input.StopInput(Input.SpecialCharacters.KEY_UP_ARROW); 215 | Thread.Sleep(millisecondDelays[2]); 216 | Input.StartInput(Input.SpecialCharacters.KEY_UP_ARROW); 217 | Thread.Sleep(millisecondDelays[3]); 218 | Input.StopInput(Input.SpecialCharacters.KEY_UP_ARROW); 219 | Thread.Sleep(millisecondDelays[4]); 220 | Input.StopInput(Input.SpecialCharacters.KEY_LEFT_ALT); 221 | break; 222 | case JumpTypes.JumpDown: 223 | Input.StartInput(Input.SpecialCharacters.KEY_DOWN_ARROW); 224 | Thread.Sleep(millisecondDelays[0]); 225 | Input.StartInput(Input.SpecialCharacters.KEY_LEFT_ALT); 226 | Thread.Sleep(millisecondDelays[1]); 227 | Input.StopInput(Input.SpecialCharacters.KEY_LEFT_ALT); 228 | Thread.Sleep(millisecondDelays[2]); 229 | Input.StopInput(Input.SpecialCharacters.KEY_DOWN_ARROW); 230 | break; 231 | } 232 | } 233 | 234 | private static List GenerateEquationCoefficients(JumpTypes jumpType, List millisecondDelays, out double maxX, out double maxY, out List jumpDataPoints) 235 | { 236 | maxX = 0; 237 | maxY = 0; 238 | PhotoTaker.StartTakingImages(75); 239 | Thread.Sleep(100); 240 | Input.StartInput(Input.SpecialCharacters.KEY_RIGHT_ARROW); 241 | TryToJump(jumpType, millisecondDelays); 242 | Thread.Sleep(2000); 243 | Input.StopInput(Input.SpecialCharacters.KEY_RIGHT_ARROW); 244 | PhotoTaker.StopTakingImages(); 245 | var photosWithTimestampDataList = PhotoTaker.GetPhotosAndDeleteFromMemory(); 246 | Vector2 previous = null; 247 | jumpDataPoints = null; 248 | Vector2 beginning = null; 249 | List dataPoints = null; 250 | GenerateEquationCoefficientsStatuses status = GenerateEquationCoefficientsStatuses.Unstarted; 251 | var playerImage = Imaging.GetImageFromFile(Imaging.ImageFiles.PlayerMiniMap); 252 | foreach (var curPhoto in photosWithTimestampDataList) 253 | { 254 | var curMinimap = Imaging.CropImage(curPhoto.Photo, Imaging.MiniMapRect); 255 | if (!Imaging.FindBitmap(new List() { playerImage }, curMinimap, out List locations)) 256 | { 257 | continue; 258 | } 259 | Vector2 cur = locations[0]; 260 | switch (status) 261 | { 262 | case GenerateEquationCoefficientsStatuses.Unstarted: 263 | beginning = cur; 264 | status = GenerateEquationCoefficientsStatuses.FindingInitialYMovement; 265 | break; 266 | case GenerateEquationCoefficientsStatuses.FindingInitialYMovement: 267 | previous = cur; 268 | if (cur.Y == beginning.Y && cur.X == beginning.X) 269 | { 270 | continue; 271 | } 272 | dataPoints = new List() { previous, cur }; 273 | status = GenerateEquationCoefficientsStatuses.FindingYMovementStop; 274 | break; 275 | case GenerateEquationCoefficientsStatuses.FindingYMovementStop: 276 | 277 | if (cur.Y == dataPoints[0].Y) 278 | { 279 | status = GenerateEquationCoefficientsStatuses.Finished; 280 | } 281 | else 282 | { 283 | dataPoints.Add(cur); 284 | } 285 | previous = cur; 286 | break; 287 | } 288 | if (status == GenerateEquationCoefficientsStatuses.Finished) 289 | { 290 | break; 291 | } 292 | } 293 | photosWithTimestampDataList.Clear(); 294 | // attempt to reset location 295 | Input.StartInput(Input.SpecialCharacters.KEY_LEFT_ARROW); 296 | Thread.Sleep(3000); 297 | Input.StopInput(Input.SpecialCharacters.KEY_LEFT_ARROW); 298 | Thread.Sleep(100); 299 | Input.StartInput(Input.SpecialCharacters.KEY_RIGHT_ARROW); 300 | //TryToJump(jumpType, millisecondDelays); 301 | Thread.Sleep(100); 302 | Input.StopInput(Input.SpecialCharacters.KEY_RIGHT_ARROW); 303 | if (dataPoints == null || dataPoints.Count == 0) 304 | { 305 | return new List(); 306 | } 307 | var originalDataPoint = dataPoints[0]; 308 | // normalize 309 | dataPoints = dataPoints.Select(x => { return new Vector2(x.X - originalDataPoint.X, x.Y - originalDataPoint.Y); }).ToList(); 310 | if (!dataPoints.Where(x => x.Y > 0).Any()) 311 | { 312 | return new List(); 313 | } 314 | maxX = dataPoints.Select(x => x.X).Max(); 315 | maxY = dataPoints.Select(x => x.Y).Max(); 316 | jumpDataPoints = dataPoints; 317 | return MapleMath.PolynomialRegressionCoefficients(dataPoints); 318 | } 319 | } 320 | } 321 | -------------------------------------------------------------------------------- /Maple/Data/MapleMath.cs: -------------------------------------------------------------------------------- 1 | using Accord.Math; 2 | using Accord.Math.Optimization.Losses; 3 | using Accord.Statistics.Models.Regression.Linear; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Maple.Data 11 | { 12 | public class Vector2 13 | { 14 | public double X; 15 | public double Y; 16 | public Vector2(double x, double y) 17 | { 18 | X = x; 19 | Y = y; 20 | } 21 | } 22 | 23 | public class MapleMath 24 | { 25 | public struct Line 26 | { 27 | public double x1 { get; set; } 28 | public double y1 { get; set; } 29 | 30 | public double x2 { get; set; } 31 | public double y2 { get; set; } 32 | 33 | public Line(Vector2 begin, Vector2 end) 34 | { 35 | x1 = begin.X; 36 | x2 = end.X; 37 | y1 = begin.Y; 38 | y2 = end.Y; 39 | } 40 | } 41 | 42 | public class LineIntersection 43 | { 44 | // Returns Point of intersection if do intersect otherwise default Point (null) 45 | public static bool FindIntersection(Line lineA, Line lineB, out Vector2 intersection, double tolerance = 0.001) 46 | { 47 | intersection = null; 48 | double x1 = lineA.x1, y1 = lineA.y1; 49 | double x2 = lineA.x2, y2 = lineA.y2; 50 | 51 | double x3 = lineB.x1, y3 = lineB.y1; 52 | double x4 = lineB.x2, y4 = lineB.y2; 53 | 54 | // equations of the form x = c (two vertical lines) 55 | if (Math.Abs(x1 - x2) < tolerance && Math.Abs(x3 - x4) < tolerance && Math.Abs(x1 - x3) < tolerance) 56 | { 57 | // Both lines overlap vertically, ambiguous intersection points. 58 | return false; 59 | } 60 | 61 | //equations of the form y=c (two horizontal lines) 62 | if (Math.Abs(y1 - y2) < tolerance && Math.Abs(y3 - y4) < tolerance && Math.Abs(y1 - y3) < tolerance) 63 | { 64 | // Both lines overlap horizontally, ambiguous intersection points. 65 | return false; 66 | } 67 | 68 | //equations of the form x=c (two vertical parallel lines) 69 | if (Math.Abs(x1 - x2) < tolerance && Math.Abs(x3 - x4) < tolerance) 70 | { 71 | //return default (no intersection) 72 | return false; 73 | } 74 | 75 | //equations of the form y=c (two horizontal parallel lines) 76 | if (Math.Abs(y1 - y2) < tolerance && Math.Abs(y3 - y4) < tolerance) 77 | { 78 | //return default (no intersection) 79 | return false; 80 | } 81 | 82 | //general equation of line is y = mx + c where m is the slope 83 | //assume equation of line 1 as y1 = m1x1 + c1 84 | //=> -m1x1 + y1 = c1 ----(1) 85 | //assume equation of line 2 as y2 = m2x2 + c2 86 | //=> -m2x2 + y2 = c2 -----(2) 87 | //if line 1 and 2 intersect then x1=x2=x & y1=y2=y where (x,y) is the intersection point 88 | //so we will get below two equations 89 | //-m1x + y = c1 --------(3) 90 | //-m2x + y = c2 --------(4) 91 | 92 | double x, y; 93 | 94 | //lineA is vertical x1 = x2 95 | //slope will be infinity 96 | //so lets derive another solution 97 | if (Math.Abs(x1 - x2) < tolerance) 98 | { 99 | //compute slope of line 2 (m2) and c2 100 | double m2 = (y4 - y3) / (x4 - x3); 101 | double c2 = -m2 * x3 + y3; 102 | 103 | //equation of vertical line is x = c 104 | //if line 1 and 2 intersect then x1=c1=x 105 | //subsitute x=x1 in (4) => -m2x1 + y = c2 106 | // => y = c2 + m2x1 107 | x = x1; 108 | y = c2 + m2 * x1; 109 | } 110 | //lineB is vertical x3 = x4 111 | //slope will be infinity 112 | //so lets derive another solution 113 | else if (Math.Abs(x3 - x4) < tolerance) 114 | { 115 | //compute slope of line 1 (m1) and c2 116 | double m1 = (y2 - y1) / (x2 - x1); 117 | double c1 = -m1 * x1 + y1; 118 | 119 | //equation of vertical line is x = c 120 | //if line 1 and 2 intersect then x3=c3=x 121 | //subsitute x=x3 in (3) => -m1x3 + y = c1 122 | // => y = c1 + m1x3 123 | x = x3; 124 | y = c1 + m1 * x3; 125 | } 126 | //lineA & lineB are not vertical 127 | //(could be horizontal we can handle it with slope = 0) 128 | else 129 | { 130 | //compute slope of line 1 (m1) and c2 131 | double m1 = (y2 - y1) / (x2 - x1); 132 | double c1 = -m1 * x1 + y1; 133 | 134 | //compute slope of line 2 (m2) and c2 135 | double m2 = (y4 - y3) / (x4 - x3); 136 | double c2 = -m2 * x3 + y3; 137 | 138 | //solving equations (3) & (4) => x = (c1-c2)/(m2-m1) 139 | //plugging x value in equation (4) => y = c2 + m2 * x 140 | x = (c1 - c2) / (m2 - m1); 141 | y = c2 + m2 * x; 142 | 143 | //verify by plugging intersection point (x, y) 144 | //in orginal equations (1) & (2) to see if they intersect 145 | //otherwise x,y values will not be finite and will fail this check 146 | if (!(Math.Abs(-m1 * x + y - c1) < tolerance 147 | && Math.Abs(-m2 * x + y - c2) < tolerance)) 148 | { 149 | //return default (no intersection) 150 | return false; 151 | } 152 | } 153 | 154 | //x,y can intersect outside the line segment since line is infinitely long 155 | //so finally check if x, y is within both the line segments 156 | if (IsInsideLine(lineA, x, y) && 157 | IsInsideLine(lineB, x, y)) 158 | { 159 | intersection = new Vector2(x, y); 160 | return true; 161 | } 162 | 163 | //return default (no intersection) 164 | return false; 165 | 166 | } 167 | 168 | // Returns true if given point(x,y) is inside the given line segment 169 | private static bool IsInsideLine(Line line, double x, double y) 170 | { 171 | return (x >= line.x1 && x <= line.x2 172 | || x >= line.x2 && x <= line.x1) 173 | && (y >= line.y1 && y <= line.y2 174 | || y >= line.y2 && y <= line.y1); 175 | } 176 | } 177 | 178 | internal class PolynomialRegressionData 179 | { 180 | private PolynomialRegression poly; 181 | public PolynomialRegressionData(List pointData, int maxDegree = 100) 182 | { 183 | double[] inputs = pointData.Select(x => (double)x.X).ToArray(); 184 | double[] outputs = pointData.Select(x => (double)x.Y).ToArray(); 185 | poly = null; 186 | double[] pred; 187 | int degree = 1; 188 | double error = 0.0; 189 | do 190 | { 191 | var ls = new PolynomialLeastSquares() 192 | { 193 | Degree = degree++ 194 | }; 195 | try 196 | { 197 | poly = ls.Learn(inputs, outputs); 198 | } 199 | catch (Exception ex) 200 | { 201 | continue; 202 | } 203 | //string str = poly.ToString("N1"); 204 | //double[] weights = poly.Weights; 205 | //double intercept = poly.Intercept; 206 | 207 | // Finally, we can use this polynomial 208 | // to predict values for the input data 209 | pred = poly.Transform(inputs); 210 | error = new SquareLoss(outputs).Loss(pred); // 0.0 211 | if (degree > maxDegree) 212 | { 213 | return; 214 | } 215 | } while (error > 0.0001); 216 | } 217 | 218 | public List PredictData(List xValues) 219 | { 220 | // We can create a learning algorithm 221 | //var xVals = Enumerable.Range((int)inputs[0], (int)(inputs[inputs.Length - 1] - inputs[0])); 222 | double[] pred = poly.Transform(xValues.Select(Convert.ToDouble).ToArray()); 223 | List returnData = new List(); 224 | for (int i = 0; i < pred.Length; i++) 225 | { 226 | returnData.Add(new Vector2((int)xValues.ElementAt(i), (int)pred[i])); 227 | } 228 | return returnData; 229 | } 230 | 231 | public List GetCoefficients() 232 | { 233 | if (poly == null || poly.Weights == null) 234 | { 235 | return new List(); 236 | } 237 | List coefficients = poly.Weights.ToList(); 238 | coefficients.Add(poly.Intercept); 239 | return coefficients; 240 | } 241 | } 242 | 243 | public static List FindRoute(MapData map, MapPiece sourceNode, MapPiece destinationNode) 244 | { 245 | List path = new List(); 246 | path.Add(sourceNode); 247 | 248 | MapPiece currentNode = sourceNode; 249 | while (true) 250 | { 251 | //get all neighbors of current-node (nodes within transmission range) 252 | List allNeighbors = currentNode.MapPieceLinkDataList.Select(x => x.JoiningMapPiece).ToList(); 253 | 254 | //remove neighbors that are already added to path 255 | IEnumerable neighbors = from neighbor in allNeighbors 256 | where !path.Contains(neighbor) 257 | select neighbor; 258 | 259 | //stop if no neighbors or destination reached 260 | if (neighbors.Count() == 0) break; 261 | if (neighbors.Contains(destinationNode)) 262 | { 263 | path.Add(destinationNode); 264 | break; 265 | } 266 | 267 | //choose next-node (the neighbor with shortest distance to destination) 268 | double bestMinDist = double.MaxValue; 269 | MapPiece nearestNode = null; 270 | foreach (var curNeighbor in neighbors) 271 | { 272 | var curMapPieceLink = curNeighbor.MapPieceLinkDataList.Where(x => x.JoiningMapPiece.Beginning.X == destinationNode.Beginning.X && x.JoiningMapPiece.Beginning.Y == destinationNode.Beginning.Y).FirstOrDefault(); 273 | if (curMapPieceLink == null) 274 | { 275 | continue; 276 | } 277 | var curMinDist = curMapPieceLink.MinimumDistance; 278 | if (curMinDist < bestMinDist) 279 | { 280 | bestMinDist = curMinDist; 281 | nearestNode = curNeighbor; 282 | } 283 | } 284 | if (nearestNode == null) 285 | { 286 | nearestNode = neighbors.OrderBy(x => MapleMath.PixelCoordinateDistance(x.Beginning, destinationNode.Beginning)).First(); // todo this isnt good 287 | } 288 | path.Add(nearestNode); 289 | currentNode = nearestNode; 290 | } 291 | 292 | return (path); 293 | } 294 | 295 | /*public static Vector2 CorrectImageHeight(Vector2 pixelCoordinate, int imageHeight) 296 | { 297 | return new Vector2(pixelCoordinate.X, Math.Abs(pixelCoordinate.Y - imageHeight)); 298 | }*/ 299 | 300 | public static int PixelCoordinateToPixel(Vector2 pixelLocation, int imageWidth) 301 | { 302 | return (int)(pixelLocation.Y * imageWidth + pixelLocation.X); 303 | } 304 | 305 | public static double PixelCoordinateDistance(Vector2 pixelCoordinate1, Vector2 pixelCoordinate2) 306 | { 307 | return Math.Sqrt(Math.Pow(pixelCoordinate2.X - pixelCoordinate1.X, 2) + Math.Pow(pixelCoordinate2.Y - pixelCoordinate1.Y, 2)); 308 | } 309 | 310 | public static Vector2 MapCoordinatesToMiniMapCoordinates(Vector2 mapCoordinates, Vector2 playerScreenLocation, Vector2 playerMinimapLocation) 311 | { 312 | double mapCoordinatesChangeX = (mapCoordinates.X - playerScreenLocation.X) * MapData.MinimapToPixelRatio; 313 | double mapCoordinatesChangeY = (mapCoordinates.Y - playerScreenLocation.Y) * MapData.MinimapToPixelRatio; 314 | return new Vector2((int)(playerMinimapLocation.X + mapCoordinatesChangeX), (int)(playerMinimapLocation.Y + mapCoordinatesChangeY)); 315 | } 316 | 317 | public static bool LocationWithinBounds(Vector2 locationToCheck, Vector2 minLocation, Vector2 maxLocation) 318 | { 319 | return (locationToCheck.X >= minLocation.X && locationToCheck.X <= maxLocation.X 320 | && locationToCheck.Y >= minLocation.Y && locationToCheck.Y <= maxLocation.Y); 321 | } 322 | 323 | public static Vector2 GetAverage(List coordinateDataList) 324 | { 325 | double totalX = 0; 326 | double totalY = 0; 327 | foreach (var curCoordinate in coordinateDataList) 328 | { 329 | totalX += curCoordinate.X; 330 | totalY += curCoordinate.Y; 331 | } 332 | return new Vector2(totalX / coordinateDataList.Count, totalY / coordinateDataList.Count); 333 | } 334 | 335 | public static List PolynomialRegressionCoefficients(List pointData) 336 | { 337 | PolynomialRegressionData poly = new PolynomialRegressionData(pointData); 338 | return poly.GetCoefficients(); 339 | } 340 | 341 | public static List PolynomialLeastSquares(List pointData) 342 | { 343 | PolynomialRegressionData poly = new PolynomialRegressionData(pointData); 344 | var xVals = Enumerable.Range((int)pointData[0].X, (int)(pointData[pointData.Count - 1].X - pointData[0].X)); 345 | return poly.PredictData(xVals.ToList()); 346 | } 347 | 348 | } 349 | } 350 | -------------------------------------------------------------------------------- /Maple/Data/MapleSerialPort.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO.Ports; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace Maple.Data 10 | { 11 | public class MapleSerialPort 12 | { 13 | private SerialPort ArduinoPortData; 14 | private string _portName; 15 | public MapleSerialPort(string portName, string comNumber) 16 | { 17 | ArduinoPortData = new SerialPort(comNumber, 9600); 18 | ArduinoPortData.RtsEnable = true; 19 | ArduinoPortData.Open(); 20 | _portName = portName; 21 | //ArduinoPortData.DataReceived += ArduinoDataReceived; 22 | ReadThread = new Thread(Read) { Name = "Maple Serial Port REad Thread" }; 23 | ReadThread.Start(); 24 | } 25 | 26 | Thread ReadThread; 27 | 28 | private void Read() 29 | { 30 | while (true) 31 | { 32 | string s = ArduinoPortData.ReadExisting(); 33 | if (s.Length > 0) 34 | { 35 | //Console.WriteLine($"Data Received from {_portName} [{s}]"); 36 | } 37 | Thread.Sleep(100); 38 | } 39 | } 40 | 41 | public void SendData(string message) 42 | { 43 | ArduinoPortData.RtsEnable = false; 44 | char endString = '#'; 45 | ArduinoPortData.Write($"{message} {endString}"); 46 | ArduinoPortData.RtsEnable = true; 47 | } 48 | 49 | ~MapleSerialPort() 50 | { 51 | ReadThread.Join(); 52 | ArduinoPortData.Close(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Maple/Data/MobData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Maple.Data 8 | { 9 | public class MobCluster 10 | { 11 | public List Locations; 12 | 13 | public Vector2 Center 14 | { 15 | get { return MapleMath.GetAverage(Locations); } 16 | } 17 | 18 | public MobCluster(Vector2 location) 19 | { 20 | Locations = new List() { location }; 21 | } 22 | 23 | public MobCluster() 24 | { 25 | Locations = new List(); 26 | } 27 | 28 | public void AddHit(Vector2 newLocation) 29 | { 30 | Locations.Add(newLocation); 31 | } 32 | 33 | public static List FindMobClustersFromPixelData(List mobLocations, int imageWidth, int imageHeight, int maxVerticalClusterDistance = 100, int maxHorizontalClusterDistance = 300) 34 | { 35 | List mobClusters = new List(); 36 | foreach (var curMobLocation in mobLocations) 37 | { 38 | var curCoordinate = curMobLocation; 39 | bool added = false; 40 | foreach (var curMobCluster in mobClusters) 41 | { 42 | double verticalDistance = Math.Abs(curCoordinate.Y - curMobCluster.Center.Y); 43 | double horizontalDistance = Math.Abs(curCoordinate.X - curMobCluster.Center.X); 44 | //double distance = MapleMath.PixelCoordinateDistance(curCoordinate, curMobCluster.Center); 45 | if (verticalDistance < maxVerticalClusterDistance 46 | && horizontalDistance < maxHorizontalClusterDistance) 47 | { 48 | curMobCluster.AddHit(curCoordinate); 49 | added = true; 50 | break; 51 | } 52 | } 53 | if (!added) 54 | { 55 | mobClusters.Add(new MobCluster(curCoordinate)); 56 | } 57 | } 58 | return mobClusters; 59 | } 60 | } 61 | 62 | public enum MobNames 63 | { 64 | BlueRaspberryJellyJuice, 65 | EnragedEspressoMachine 66 | } 67 | 68 | public class MobData 69 | { 70 | public static Dictionary> MobNamesToImagingFiles = new Dictionary>() 71 | { 72 | { MobNames.BlueRaspberryJellyJuice, new List() 73 | { 74 | Imaging.ImageFiles.BlueRaspberryJellyJuiceLeft, 75 | Imaging.ImageFiles.BlueRaspberryJellyJuiceRight 76 | } 77 | }, 78 | { MobNames.EnragedEspressoMachine, new List() 79 | { 80 | Imaging.ImageFiles.BlueEspressoMachineLeft, 81 | Imaging.ImageFiles.BlueEspressoMachineRight 82 | } 83 | }, 84 | }; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Maple/Data/SkillData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace Maple.Data 9 | { 10 | public class SkillData 11 | { 12 | public string SkillName { get; set; } 13 | public int DiscrepencyTimeMillis { get; set; } 14 | private int _currentDiscrepencyTimeMillis; 15 | public int HoldMillis { get; set; } 16 | public int HoldDiscrepencyTimeMillis { get; set; } 17 | 18 | public char Key { get; set; } 19 | public int RefreshMillis { get; set; } 20 | public bool UseOnLogin { get; set; } 21 | public static Random rand = new Random(); 22 | public DateTime NextUseTime 23 | { 24 | get { return LastUseTime + new TimeSpan(0, 0, 0, 0, RefreshMillis + _currentDiscrepencyTimeMillis); } 25 | } 26 | 27 | public DateTime LastUseTime; 28 | 29 | public void UseSkill() 30 | { 31 | Input.StartInput(Key); 32 | Thread.Sleep(HoldMillis); 33 | Input.StopInput(Key); 34 | _currentDiscrepencyTimeMillis = rand.Next(DiscrepencyTimeMillis); 35 | LastUseTime = DateTime.Now; 36 | } 37 | 38 | public SkillData() 39 | { 40 | 41 | 42 | 43 | LastUseTime = DateTime.Now; 44 | 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Maple/Images/BlueEspressoMachineLeft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/BlueEspressoMachineLeft.png -------------------------------------------------------------------------------- /Maple/Images/BlueEspressoMachineRight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/BlueEspressoMachineRight.png -------------------------------------------------------------------------------- /Maple/Images/BlueRaspberryJellyJuiceLeft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/BlueRaspberryJellyJuiceLeft.png -------------------------------------------------------------------------------- /Maple/Images/BlueRaspberryJellyJuiceRight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/BlueRaspberryJellyJuiceRight.png -------------------------------------------------------------------------------- /Maple/Images/ChangeChannel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/ChangeChannel.png -------------------------------------------------------------------------------- /Maple/Images/CharacterSelectionCharacterSlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/CharacterSelectionCharacterSlot.png -------------------------------------------------------------------------------- /Maple/Images/ClaimReward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/ClaimReward.png -------------------------------------------------------------------------------- /Maple/Images/ContentGuide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/ContentGuide.png -------------------------------------------------------------------------------- /Maple/Images/DemonAvengerName.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/DemonAvengerName.png -------------------------------------------------------------------------------- /Maple/Images/FullHealthBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/FullHealthBar.png -------------------------------------------------------------------------------- /Maple/Images/HP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/HP.png -------------------------------------------------------------------------------- /Maple/Images/HealthBarDropping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/HealthBarDropping.png -------------------------------------------------------------------------------- /Maple/Images/HealthBarEmpty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/HealthBarEmpty.png -------------------------------------------------------------------------------- /Maple/Images/LeftHealthBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/LeftHealthBar.png -------------------------------------------------------------------------------- /Maple/Images/OtherPlayerMiniMap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/OtherPlayerMiniMap.png -------------------------------------------------------------------------------- /Maple/Images/OverheadQuest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/OverheadQuest.png -------------------------------------------------------------------------------- /Maple/Images/PlayerMiniMap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/PlayerMiniMap.png -------------------------------------------------------------------------------- /Maple/Images/RebootServer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/RebootServer.png -------------------------------------------------------------------------------- /Maple/Images/RebootServerChannelSelect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/RebootServerChannelSelect.png -------------------------------------------------------------------------------- /Maple/Images/Rune.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/Rune.png -------------------------------------------------------------------------------- /Maple/Images/RuneMiniMap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/RuneMiniMap.png -------------------------------------------------------------------------------- /Maple/Images/TheNextLegendTitle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/TheNextLegendTitle.png -------------------------------------------------------------------------------- /Maple/Images/badguy1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/badguy1.png -------------------------------------------------------------------------------- /Maple/Images/map1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/map1.png -------------------------------------------------------------------------------- /Maple/Images/runetest1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/runetest1.png -------------------------------------------------------------------------------- /Maple/Images/runetest2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/runetest2.png -------------------------------------------------------------------------------- /Maple/Images/runetest3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/runetest3.png -------------------------------------------------------------------------------- /Maple/Images/runetest4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/runetest4.png -------------------------------------------------------------------------------- /Maple/Images/runetest5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cubman3134/MapleStoryBot/ad87ced536cfd9739a4e7061e3c11ff3f0c70ef3/Maple/Images/runetest5.png -------------------------------------------------------------------------------- /Maple/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |