├── .gitignore ├── DEBUG.md ├── LICENSE ├── Mappy.sln ├── Mappy ├── API.cs ├── App.Designer.cs ├── App.config ├── App.cs ├── App.resx ├── Entities │ ├── Entity.cs │ └── MapIcon.cs ├── FodyWeavers.xml ├── Helpers │ ├── AppHelper.cs │ ├── GameMemory.cs │ ├── Logger.cs │ └── MapHelper.cs ├── MapViewer.Designer.cs ├── MapViewer.cs ├── MapViewer.resx ├── Mappy.csproj ├── NLog.config ├── NLog.xsd ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Resources │ └── xivapi.png ├── Settings.cs ├── Tracking │ ├── Saver.cs │ ├── Tracking.cs │ ├── TrackingEnemies.cs │ ├── TrackingNpcs.cs │ └── TrackingPlayer.cs ├── Viewer.Designer.cs ├── Viewer.cs ├── Viewer.resx ├── assets │ ├── aether.png │ ├── enemy.png │ ├── gathering.png │ ├── highlight.png │ ├── map_default.png │ ├── map_loading.png │ ├── npc.png │ ├── object.png │ ├── player.png │ ├── trail.png │ ├── trailmini.png │ └── unknown.png ├── favicon.ico ├── icon.ico └── packages.config ├── README.md ├── app.png ├── example_data.txt ├── favicon.ico ├── signatures-x64.json └── structures-x64.json /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | 56 | # StyleCop 57 | StyleCopReport.xml 58 | 59 | # Files built by Visual Studio 60 | *_i.c 61 | *_p.c 62 | *_h.h 63 | *.ilk 64 | *.meta 65 | *.obj 66 | *.iobj 67 | *.pch 68 | *.pdb 69 | *.ipdb 70 | *.pgc 71 | *.pgd 72 | *.rsp 73 | *.sbr 74 | *.tlb 75 | *.tli 76 | *.tlh 77 | *.tmp 78 | *.tmp_proj 79 | *.log 80 | *.vspscc 81 | *.vssscc 82 | .builds 83 | *.pidb 84 | *.svclog 85 | *.scc 86 | 87 | # Chutzpah Test files 88 | _Chutzpah* 89 | 90 | # Visual C++ cache files 91 | ipch/ 92 | *.aps 93 | *.ncb 94 | *.opendb 95 | *.opensdf 96 | *.sdf 97 | *.cachefile 98 | *.VC.db 99 | *.VC.VC.opendb 100 | 101 | # Visual Studio profiler 102 | *.psess 103 | *.vsp 104 | *.vspx 105 | *.sap 106 | 107 | # Visual Studio Trace Files 108 | *.e2e 109 | 110 | # TFS 2012 Local Workspace 111 | $tf/ 112 | 113 | # Guidance Automation Toolkit 114 | *.gpState 115 | 116 | # ReSharper is a .NET coding add-in 117 | _ReSharper*/ 118 | *.[Rr]e[Ss]harper 119 | *.DotSettings.user 120 | 121 | # JustCode is a .NET coding add-in 122 | .JustCode 123 | 124 | # TeamCity is a build add-in 125 | _TeamCity* 126 | 127 | # DotCover is a Code Coverage Tool 128 | *.dotCover 129 | 130 | # AxoCover is a Code Coverage Tool 131 | .axoCover/* 132 | !.axoCover/settings.json 133 | 134 | # Visual Studio code coverage results 135 | *.coverage 136 | *.coveragexml 137 | 138 | # NCrunch 139 | _NCrunch_* 140 | .*crunch*.local.xml 141 | nCrunchTemp_* 142 | 143 | # MightyMoose 144 | *.mm.* 145 | AutoTest.Net/ 146 | 147 | # Web workbench (sass) 148 | .sass-cache/ 149 | 150 | # Installshield output folder 151 | [Ee]xpress/ 152 | 153 | # DocProject is a documentation generator add-in 154 | DocProject/buildhelp/ 155 | DocProject/Help/*.HxT 156 | DocProject/Help/*.HxC 157 | DocProject/Help/*.hhc 158 | DocProject/Help/*.hhk 159 | DocProject/Help/*.hhp 160 | DocProject/Help/Html2 161 | DocProject/Help/html 162 | 163 | # Click-Once directory 164 | publish/ 165 | 166 | # Publish Web Output 167 | *.[Pp]ublish.xml 168 | *.azurePubxml 169 | # Note: Comment the next line if you want to checkin your web deploy settings, 170 | # but database connection strings (with potential passwords) will be unencrypted 171 | *.pubxml 172 | *.publishproj 173 | 174 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 175 | # checkin your Azure Web App publish settings, but sensitive information contained 176 | # in these scripts will be unencrypted 177 | PublishScripts/ 178 | 179 | # NuGet Packages 180 | *.nupkg 181 | # The packages folder can be ignored because of Package Restore 182 | **/[Pp]ackages/* 183 | # except build/, which is used as an MSBuild target. 184 | !**/[Pp]ackages/build/ 185 | # Uncomment if necessary however generally it will be regenerated when needed 186 | #!**/[Pp]ackages/repositories.config 187 | # NuGet v3's project.json files produces more ignorable files 188 | *.nuget.props 189 | *.nuget.targets 190 | 191 | # Microsoft Azure Build Output 192 | csx/ 193 | *.build.csdef 194 | 195 | # Microsoft Azure Emulator 196 | ecf/ 197 | rcf/ 198 | 199 | # Windows Store app package directories and files 200 | AppPackages/ 201 | BundleArtifacts/ 202 | Package.StoreAssociation.xml 203 | _pkginfo.txt 204 | *.appx 205 | 206 | # Visual Studio cache files 207 | # files ending in .cache can be ignored 208 | *.[Cc]ache 209 | # but keep track of directories ending in .cache 210 | !*.[Cc]ache/ 211 | 212 | # Others 213 | ClientBin/ 214 | ~$* 215 | *~ 216 | *.dbmdl 217 | *.dbproj.schemaview 218 | *.jfm 219 | *.pfx 220 | *.publishsettings 221 | orleans.codegen.cs 222 | 223 | # Including strong name files can present a security risk 224 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 225 | #*.snk 226 | 227 | # Since there are multiple workflows, uncomment next line to ignore bower_components 228 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 229 | #bower_components/ 230 | 231 | # RIA/Silverlight projects 232 | Generated_Code/ 233 | 234 | # Backup & report files from converting an old project file 235 | # to a newer Visual Studio version. Backup files are not needed, 236 | # because we have git ;-) 237 | _UpgradeReport_Files/ 238 | Backup*/ 239 | UpgradeLog*.XML 240 | UpgradeLog*.htm 241 | ServiceFabricBackup/ 242 | *.rptproj.bak 243 | 244 | # SQL Server files 245 | *.mdf 246 | *.ldf 247 | *.ndf 248 | 249 | # Business Intelligence projects 250 | *.rdl.data 251 | *.bim.layout 252 | *.bim_*.settings 253 | *.rptproj.rsuser 254 | 255 | # Microsoft Fakes 256 | FakesAssemblies/ 257 | 258 | # GhostDoc plugin setting file 259 | *.GhostDoc.xml 260 | 261 | # Node.js Tools for Visual Studio 262 | .ntvs_analysis.dat 263 | node_modules/ 264 | 265 | # Visual Studio 6 build log 266 | *.plg 267 | 268 | # Visual Studio 6 workspace options file 269 | *.opt 270 | 271 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 272 | *.vbw 273 | 274 | # Visual Studio LightSwitch build output 275 | **/*.HTMLClient/GeneratedArtifacts 276 | **/*.DesktopClient/GeneratedArtifacts 277 | **/*.DesktopClient/ModelManifest.xml 278 | **/*.Server/GeneratedArtifacts 279 | **/*.Server/ModelManifest.xml 280 | _Pvt_Extensions 281 | 282 | # Paket dependency manager 283 | .paket/paket.exe 284 | paket-files/ 285 | 286 | # FAKE - F# Make 287 | .fake/ 288 | 289 | # JetBrains Rider 290 | .idea/ 291 | *.sln.iml 292 | 293 | # CodeRush 294 | .cr/ 295 | 296 | # Python Tools for Visual Studio (PTVS) 297 | __pycache__/ 298 | *.pyc 299 | 300 | # Cake - Uncomment if you are using it 301 | # tools/** 302 | # !tools/packages.config 303 | 304 | # Tabs Studio 305 | *.tss 306 | 307 | # Telerik's JustMock configuration file 308 | *.jmconfig 309 | 310 | # BizTalk build output 311 | *.btp.cs 312 | *.btm.cs 313 | *.odx.cs 314 | *.xsd.cs 315 | 316 | # OpenCover UI analysis results 317 | OpenCover/ 318 | 319 | # Azure Stream Analytics local run output 320 | ASALocalRun/ 321 | 322 | # MSBuild Binary and Structured Log 323 | *.binlog 324 | 325 | # NVidia Nsight GPU debugger configuration file 326 | *.nvuser 327 | 328 | # MFractors (Xamarin productivity tool) working folder 329 | .mfractor/ 330 | 331 | # Local History for Visual Studio 332 | .localhistory/ -------------------------------------------------------------------------------- /DEBUG.md: -------------------------------------------------------------------------------- 1 | # Mappy 2 | 3 | Mapping application for Maps. 4 | 5 | This mapper comes with custom json structures, do not delete that file!!!!!!!!!!!!!!!!!!!! 6 | 7 | ### To update decimals: 8 | 9 | This project uses custom **MAPINFO** and **ZONEINFO** decimals, for example: 10 | 11 | ```json 12 | { 13 | "Key": "MAPINFO", 14 | "Value": "", 15 | "SigScanAddress": { 16 | "value": 0 17 | }, 18 | "ASMSignature": false, 19 | "Offset": 0, 20 | "PointerPath": [ 21 | 25198120 22 | ] 23 | }, 24 | { 25 | "Key": "ZONEINFO", 26 | "Value": "", 27 | "SigScanAddress": { 28 | "value": 0 29 | }, 30 | "ASMSignature": false, 31 | "Offset": 0, 32 | "PointerPath": [ 33 | 24893876 34 | ] 35 | }, 36 | ``` 37 | 38 | ## Finding offset again for Mapper: 39 | 40 | **MAP TERRITORY** 41 | 42 | | ID | Map | 43 | | --- | --- | 44 | | 166 | Haukke Manor | 45 | | 134 | Summerford Farms | 46 | | 135 | Lower La Noscea | 47 | 48 | ### Haukke Manor 49 | 50 | **MAP IDs** 51 | 52 | | ID | Name | 53 | | --- | --- | 54 | | 48 | Ground Floor | 55 | | 54 | Second Floor | 56 | | 55 | Cellerage | 57 | 58 | **MAP ZONE** 59 | 60 | | ID | Name | 61 | | --- | --- | 62 | | 599 | Ground Floor | 63 | | 600 | Second Floor | 64 | | 601 | Cellerage | 65 | 66 | 67 | Finding offset using cheat engine!: 68 | 69 | - Go to Haukku 70 | - Do first boss and open celleter 71 | - Going up/down the stairs (first steep) will switch between Cellarage and Ground floor 72 | - Go to ground floor (This is the first floor you're on) 73 | - Open Cheat engine 74 | - Attach to ffxiv_dx11 75 | - You do not need to chang any other settings 76 | - In Value enter: 599 77 | - Press "First Scan" 78 | - A lot of stuff will be found 79 | - In game, go down the steps until "cellarage" shows up on the screen (and the map changes) 80 | - Go back on cheat engine and enter 601 and click "NEXT SCAN" 81 | - Keep repeating until you get 1 or a "few" entries 82 | - The correct/final address will be in **GREEN** 83 | - Once you find the green address, double click it. 84 | - You now have the value in your list at the bottom 85 | - If you run up and down stairs this should change between 601 and 599 in REAL-TIME 86 | - In the list at the bottom, double click the "address" bit (the 7FF7ED8CXXXX bit) 87 | - A modal will appear called "Change address" 88 | - You should see something like: `ffxiv_dx11.exe+17BD9BC` in the **Address:** field 89 | - Open up windows calculator, change to "Programmer" mode and click "Hex" 90 | - Paste the values after the + in. eg: `17BD9BC` 91 | - Switch back to Decimal, and copy the number, eg: 24893884 92 | - Minus 8 from it 93 | - That number is your "offset" 94 | - In mappy app: 95 | - Open `signatures-x64.json` in sublime or a text editor 96 | - Look for the entry: **ZONEINFO** `"Key": "ZONEINFO",` 97 | - Ensure `ASMSignature` is `false` 98 | - Remove any values in `PointerPath` (it might have 0,0 inside it) 99 | - Add the new decimal in there, you should have something like this: 100 | 101 | ```json 102 | { 103 | "ASMSignature": false, 104 | "Key": "ZONEINFO", 105 | "PointerPath": [ 106 | 25925516 107 | ], 108 | "Value": "4056415641578b9108be0000488bf1448b35" 109 | }, 110 | ``` 111 | 112 | - Restart the app 113 | 114 | To confirm this, close the game and restart it. Repeat the whole process and you should get the same number/address, or just wing it :D 115 | 116 | If you need to fix **MAPINFO** then use the same process and use the values from **Haukke Manor MAP IDs** above. 117 | 118 | 119 | ## some data 120 | 121 | Teleport to summerford farms 122 | 123 | ``` 124 | Map ID: 15 125 | Map Index: 162 126 | Map Territory: 134 127 | ``` 128 | 129 | ``` 130 | Outputting Target: 131 | 132 | Name: Tiny Mandragora 133 | Level: 5 134 | HP: 91/91 135 | MP: 0/0 136 | Model ID: 1053917952 137 | NPCID 1: 3929859 138 | NPCID 2: 118 139 | Owner ID: 3758096384 140 | Memory ID: 1073884831 141 | Map ID: 15 142 | Map Index: 162 143 | Map Territory: 134 144 | Is Casting: No 145 | Is Claimed: No 146 | Is Fate: No 147 | Status: Idle 148 | Type: Monster 149 | Target Type: 232 150 | Position: X 119.310180664063 / Y -169.146240234375 / Z 72.6660614013672 151 | Distance from player: 31.82966 152 | --------------------------------------------------------- 153 | ``` 154 | 155 | 156 | coerthas central highlands 157 | ``` 158 | Outputting Target: 159 | 160 | Name: House Fortemps Guard 161 | Level: 41 162 | HP: 9185/9185 163 | MP: 8150/8150 164 | Model ID: 1073002752 165 | NPCID 1: 4291467 166 | NPCID 2: 1774 167 | Owner ID: 3758096384 168 | Memory ID: 1073742831 169 | Map ID: 53 170 | Map Index: 380 171 | Map Territory: 155 172 | Is Casting: No 173 | Is Claimed: No 174 | Is Fate: No 175 | Status: Idle 176 | Type: Monster 177 | Target Type: 232 178 | Position: X 177.878494262695 / Y -190.71240234375 / Z 301.664611816406 179 | Distance from player: 19.64223 180 | --------------------------------------------------------- 181 | 182 | ``` 183 | 184 | ### Cheat engine lua debug code 185 | 186 | ``` 187 | THE BLACK SHROUD 188 | 189 | Map ID: 6 190 | Map Index: 78 191 | Map Territory: 153 192 | 193 | 194 | function _sigScan() 195 | local results=AOBScan("48897C243833FF89B9C0000000C681CD000000008B0D") 196 | if (results~=nil) then 197 | local count=stringlist_getCount(results) 198 | if (count>=1) then 199 | local address=stringlist_getString(results,0) 200 | local addrNum = tonumber(address, 16) 201 | local calcAddr = readInteger(addrNum + 22) 202 | address = string.format("%X", addrNum + 20 + calcAddr + 6) 203 | print("address: " .. address) 204 | end 205 | object_destroy(results) 206 | results=nil 207 | else 208 | print("nothing") 209 | end 210 | end 211 | _sigScan() 212 | ``` 213 | 214 | 215 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 XIVAPI 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Mappy.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26430.14 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D839E409-7220-4F16-A97D-17269E523A68}" 7 | ProjectSection(SolutionItems) = preProject 8 | C:\Users\Josh\Desktop\Roboto\Roboto-Black.ttf = C:\Users\Josh\Desktop\Roboto\Roboto-Black.ttf 9 | C:\Users\Josh\Desktop\Roboto\Roboto-BlackItalic.ttf = C:\Users\Josh\Desktop\Roboto\Roboto-BlackItalic.ttf 10 | C:\Users\Josh\Desktop\Roboto\Roboto-Bold.ttf = C:\Users\Josh\Desktop\Roboto\Roboto-Bold.ttf 11 | C:\Users\Josh\Desktop\Roboto\Roboto-BoldItalic.ttf = C:\Users\Josh\Desktop\Roboto\Roboto-BoldItalic.ttf 12 | C:\Users\Josh\Desktop\Roboto\Roboto-Italic.ttf = C:\Users\Josh\Desktop\Roboto\Roboto-Italic.ttf 13 | C:\Users\Josh\Desktop\Roboto\Roboto-Light.ttf = C:\Users\Josh\Desktop\Roboto\Roboto-Light.ttf 14 | C:\Users\Josh\Desktop\Roboto\Roboto-LightItalic.ttf = C:\Users\Josh\Desktop\Roboto\Roboto-LightItalic.ttf 15 | C:\Users\Josh\Desktop\Roboto\Roboto-Medium.ttf = C:\Users\Josh\Desktop\Roboto\Roboto-Medium.ttf 16 | C:\Users\Josh\Desktop\Roboto\Roboto-MediumItalic.ttf = C:\Users\Josh\Desktop\Roboto\Roboto-MediumItalic.ttf 17 | C:\Users\Josh\Desktop\Roboto\Roboto-Regular.ttf = C:\Users\Josh\Desktop\Roboto\Roboto-Regular.ttf 18 | C:\Users\Josh\Desktop\Roboto\Roboto-Thin.ttf = C:\Users\Josh\Desktop\Roboto\Roboto-Thin.ttf 19 | C:\Users\Josh\Desktop\Roboto\Roboto-ThinItalic.ttf = C:\Users\Josh\Desktop\Roboto\Roboto-ThinItalic.ttf 20 | EndProjectSection 21 | EndProject 22 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mappy", "Mappy\Mappy.csproj", "{A36FD888-9ACD-470B-9697-C2BC1C9266F7}" 23 | EndProject 24 | Global 25 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 26 | Debug|Any CPU = Debug|Any CPU 27 | Debug|x64 = Debug|x64 28 | Release|Any CPU = Release|Any CPU 29 | Release|x64 = Release|x64 30 | EndGlobalSection 31 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 32 | {A36FD888-9ACD-470B-9697-C2BC1C9266F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {A36FD888-9ACD-470B-9697-C2BC1C9266F7}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {A36FD888-9ACD-470B-9697-C2BC1C9266F7}.Debug|x64.ActiveCfg = Debug|x64 35 | {A36FD888-9ACD-470B-9697-C2BC1C9266F7}.Debug|x64.Build.0 = Debug|x64 36 | {A36FD888-9ACD-470B-9697-C2BC1C9266F7}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {A36FD888-9ACD-470B-9697-C2BC1C9266F7}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {A36FD888-9ACD-470B-9697-C2BC1C9266F7}.Release|x64.ActiveCfg = Release|x64 39 | {A36FD888-9ACD-470B-9697-C2BC1C9266F7}.Release|x64.Build.0 = Release|x64 40 | EndGlobalSection 41 | GlobalSection(SolutionProperties) = preSolution 42 | HideSolutionNode = FALSE 43 | EndGlobalSection 44 | GlobalSection(ExtensibilityGlobals) = postSolution 45 | SolutionGuid = {50DACDB7-7778-494A-8788-29BA315EB35D} 46 | EndGlobalSection 47 | EndGlobal 48 | -------------------------------------------------------------------------------- /Mappy/API.cs: -------------------------------------------------------------------------------- 1 | using System.Net.Http; 2 | using System; 3 | using Flurl; 4 | using Flurl.Http; 5 | using Newtonsoft.Json; 6 | using Mappy.Helpers; 7 | using System.Net; 8 | using System.IO; 9 | using Mappy.Entities; 10 | using System.Collections.Generic; 11 | 12 | namespace Mappy 13 | { 14 | static class API 15 | { 16 | private static int total = 0; 17 | private static bool requestInAction = false; 18 | private static bool enabled = false; 19 | 20 | /// 21 | /// Toggle the submitting of map data to XIVAPI 22 | /// 23 | public static void ToggleMapSubmissions() 24 | { 25 | enabled = !enabled; 26 | } 27 | 28 | public static bool IsEnabled() 29 | { 30 | return enabled; 31 | } 32 | 33 | /// 34 | /// Check an API key can submit data to XIVAPI 35 | /// 36 | public static async void CheckApiKey() 37 | { 38 | try 39 | { 40 | Logger.Add("Validating XIVAPI key..."); 41 | 42 | dynamic response = await $"{Properties.Settings.Default.ApiUrl}/mappy/check-key?private_key={Properties.Settings.Default.ApiKey}".GetJsonAsync(); 43 | App.Instance.HandleKeyVerification(response.ok, response.user); 44 | } 45 | catch (Exception ex) 46 | { 47 | Logger.Exception(ex, "Mappy -> CheckApiKey"); 48 | App.Instance.HandleKeyVerification(false, null); 49 | } 50 | } 51 | 52 | 53 | /// 54 | /// Submit some data (Even if you hard code this, there are server checks XD) 55 | /// 56 | /// 57 | /// 58 | public static async void SubmitData(string type, List data) 59 | { 60 | // if submit turned off 61 | if (!enabled || String.IsNullOrEmpty(Properties.Settings.Default.ApiKey)) { 62 | return; 63 | } 64 | 65 | total++; 66 | App.Instance.labelTotalSubmits.Text = total.ToString(); 67 | 68 | // assign a payload id 69 | Random random = new Random(); 70 | int id = 100000 + random.Next(899999); 71 | 72 | // log payload information 73 | Logger.Add($"---> [#{id}] Submitting json data to xivapi"); 74 | App.Instance.labelSubmitStatus.Text = $"(API) Sending payload: #{id}"; 75 | 76 | try { 77 | // submit to api 78 | await $"{Properties.Settings.Default.ApiUrl}/mappy/submit?private_key={Properties.Settings.Default.ApiKey}".PostJsonAsync(new 79 | { 80 | id, 81 | type, 82 | data, 83 | }); 84 | Logger.Add($"---> [#{id}] Json data submitted successfully"); 85 | App.Instance.labelSubmitStatus.Text = $"(API) Payload #{id} sent"; 86 | } catch (Exception ex) { 87 | Logger.Add($"Error: {ex.Message}"); 88 | Logger.Exception(ex, $"COULD NOT SAVE PAYLOAD: [#{id}]"); 89 | } 90 | } 91 | 92 | /// 93 | /// Get map image from XIVAPI 94 | /// 95 | /// 96 | public static async void GetMapImage(uint id) 97 | { 98 | // if a request is in action or id is zero, do nothing 99 | if (requestInAction || id == 0) { 100 | return; 101 | } 102 | 103 | requestInAction = true; 104 | 105 | try 106 | { 107 | // get map json 108 | Logger.Add($"[GET] {Properties.Settings.Default.ApiUrl}/Map/{id}"); 109 | HttpResponseMessage mapRequest = await new Url($"{Properties.Settings.Default.ApiUrl}/Map/{id}?t=123").GetAsync(); 110 | dynamic Map = JsonConvert.DeserializeObject(mapRequest.Content.ReadAsStringAsync().Result); 111 | Logger.Add($"[RESPONSE] MapID: {Map.ID}"); 112 | 113 | // get placename json 114 | Logger.Add($"[GET] {Properties.Settings.Default.ApiUrl}/PlaceName/{Map.PlaceName.ID}"); 115 | HttpResponseMessage placeNameRequest = await new Url($"{Properties.Settings.Default.ApiUrl}/PlaceName/{Map.PlaceName.ID}").GetAsync(); 116 | dynamic PlaceName = JsonConvert.DeserializeObject(placeNameRequest.Content.ReadAsStringAsync().Result); 117 | Logger.Add($"[RESPONSE] PlaceNameID: {PlaceName.ID}"); 118 | 119 | try 120 | { 121 | Logger.Add("Deserializing map data"); 122 | requestInAction = false; 123 | 124 | try 125 | { 126 | // set size factor and layer count 127 | Map.SizeFactor = (double)(Map.SizeFactor / 100.0); 128 | Map.LayerCount = PlaceName.GameContentLinks.Map.PlaceName.Count; 129 | 130 | // download map and set it on the map visual 131 | Logger.Add($"[DOWNLOAD] {Properties.Settings.Default.ApiUrl}{Map.MapFilename}"); 132 | Map.LocalFilename = DownloadImage($"{Properties.Settings.Default.ApiUrl}{Map.MapFilename}"); 133 | App.Instance.MapViewer.SetMapVisual(Map); 134 | 135 | // set axis restriction 136 | App.Instance.TrackingEnemies.SetAxisRestriction((int)Map.LayerCount > 1); 137 | App.Instance.TrackingNpcs.SetAxisRestriction((int)Map.LayerCount > 1); 138 | 139 | // enable memory timer 140 | App.Instance.StartZonedTimerCountdown(); 141 | } 142 | catch (Exception ex) 143 | { 144 | Logger.Exception(ex, "Viewer -> getMapImage (1)"); 145 | } 146 | } 147 | catch (Exception ex) 148 | { 149 | Logger.Exception(ex, "Viewer -> getMapImage (2)"); 150 | } 151 | } 152 | catch (Exception ex) 153 | { 154 | Logger.Exception(ex, "Viewer -> getMapImage (3)"); 155 | } 156 | } 157 | 158 | /// 159 | /// Download the image 160 | /// 161 | /// 162 | /// 163 | public static string DownloadImage(string filename) 164 | { 165 | if (!Directory.Exists(AppHelper.getApplicationPath() + "/maps/")) 166 | { 167 | Directory.CreateDirectory(AppHelper.getApplicationPath() + "/maps/"); 168 | } 169 | 170 | var saveto = AppHelper.getApplicationPath() + "/maps/" + Path.GetFileName(filename); 171 | 172 | // if file does not exist, download it 173 | if (!File.Exists(saveto)) 174 | { 175 | Logger.Add("downloading: " + Path.GetFileName(filename)); 176 | using (WebClient client = new WebClient()) 177 | { 178 | client.DownloadFile(filename, saveto); 179 | } 180 | } 181 | 182 | return saveto; 183 | } 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /Mappy/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | False 15 | 16 | 17 | 10 18 | 19 | 20 | hh:mm:ss tt 21 | 22 | 23 | True 24 | 25 | 26 | 200 27 | 28 | 29 | 1000 30 | 31 | 32 | False 33 | 34 | 35 | False 36 | 37 | 38 | 39 | 40 | 41 | https://xivapi.com 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Mappy/App.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using System.Collections.Generic; 4 | using System.Timers; 5 | using Mappy.Tracking; 6 | using Mappy.Helpers; 7 | using Sharlayan.Core; 8 | using System.Drawing; 9 | 10 | namespace Mappy 11 | { 12 | public partial class App : Form 13 | { 14 | public static App Instance; 15 | public MapViewer MapViewer = new MapViewer(); 16 | public Viewer DebugViewer = new Viewer(); 17 | 18 | private bool Scanning = true; 19 | public TrackingEnemies TrackingEnemies = new TrackingEnemies(); 20 | public TrackingNpcs TrackingNpcs = new TrackingNpcs(); 21 | public TrackingPlayer TrackingPlayer = new TrackingPlayer(); 22 | 23 | /// 24 | /// app 25 | /// 26 | public App() 27 | { 28 | InitializeComponent(); 29 | Instance = this; 30 | } 31 | 32 | /// 33 | /// when my app loads 34 | /// 35 | /// 36 | /// 37 | private void AppLoaded(object sender, EventArgs e) 38 | { 39 | LoadSettings(); 40 | SetupApplication(); 41 | } 42 | 43 | /// 44 | /// setup the application 45 | /// 46 | private void SetupApplication() 47 | { 48 | Logger.Geset(); 49 | 50 | Logger.Add("================================================"); 51 | Logger.Add("FINAL FANTASY XIV MAPPY"); 52 | Logger.Add("Built by: Vekien"); 53 | Logger.Add("Discord: https://discord.gg/MFFVHWC"); 54 | Logger.Add("Source: https://github.com/xivapi/xivapi-mappy"); 55 | Logger.Add(""); 56 | Logger.Add("This app reads the FFXIV Memory to look for "); 57 | Logger.Add("enemies and NPCs. Data of these findings are"); 58 | Logger.Add("stored in the /logs/ folder, you can use this"); 59 | Logger.Add("data in your own applications! You do not need a"); 60 | Logger.Add("XIVAPI Key for personal usage."); 61 | Logger.Add("If you have any problems, please ask on Discord!"); 62 | Logger.Add("================================================"); 63 | Logger.Add("Connecting to the FFXIV Game Memory ..."); 64 | SetStatus("Connecting ..."); 65 | 66 | if (GameMemory.SetGameProcess()) { 67 | InitializeTimer.Enabled = true; 68 | } else { 69 | Logger.Add("Could not connect to the games memory, stupid question... Have you started FFXIV and logged in?"); 70 | SetStatus("Could not connect to FFXIV Game Memory!"); 71 | } 72 | } 73 | 74 | /// 75 | /// called when app initialized, this is delayed 76 | /// 77 | private void Initialized() 78 | { 79 | // set player name 80 | ActorItem player = GameMemory.GetPlayer(); 81 | labelPlayerName.Text = player.Name; 82 | 83 | // create timer 84 | System.Timers.Timer aTimer = new System.Timers.Timer(); 85 | aTimer.Elapsed += (sender, e) => { 86 | ScanIntervalAction(); 87 | }; 88 | aTimer.Interval = Properties.Settings.Default.ScanTimerSpeed; 89 | aTimer.Enabled = true; 90 | } 91 | 92 | #region Log View Window 93 | 94 | private List logs = new List(); 95 | 96 | /// 97 | /// Tick timer for log view 98 | /// 99 | /// 100 | /// 101 | private void LogViewTickTimer_Tick(object sender, EventArgs e) 102 | { 103 | UpdateLogView(); 104 | } 105 | 106 | /// 107 | /// Update the visuals of the map 108 | /// 109 | public void UpdateLogView() 110 | { 111 | // if we're selecting something, don't update 112 | if (!logview.SelectedText.Equals(String.Empty)) 113 | { 114 | return; 115 | } 116 | 117 | try 118 | { 119 | List newentries = Logger.Get(logs.Count); 120 | if (newentries.Count == 0) 121 | { 122 | return; 123 | } 124 | 125 | // get log entries 126 | foreach (string entry in newentries) 127 | { 128 | logview.AppendText(entry + Environment.NewLine); 129 | logs.Add(entry); 130 | } 131 | 132 | logview.SelectionStart = logview.Text.Length; 133 | } 134 | catch { } 135 | } 136 | 137 | #endregion 138 | 139 | #region Scanning Timers 140 | 141 | /// 142 | /// Memory scan timer 143 | /// 144 | private void ScanIntervalAction() 145 | { 146 | // if scanning disabled, do nothing 147 | if (Scanning) 148 | { 149 | ActorItem player = GameMemory.GetPlayer(); 150 | 151 | // if player has moved map, disable memory timer 152 | if (TrackingPlayer.HasMovedMap()) 153 | { 154 | // clear markers 155 | TrackingEnemies.Clear(); 156 | TrackingNpcs.Clear(); 157 | 158 | // disable tickers 159 | SetScanningState(false); 160 | MapViewer.SetMapCountdown("Zoning ..."); 161 | 162 | // get the map viewer to request latest map, 163 | // once it has done it, it will renable memory timer 164 | MapViewer.RequestLatestMap(); 165 | } 166 | else 167 | { 168 | // scan for enemies 169 | TrackingEnemies.Scan(); 170 | TrackingNpcs.Scan(); 171 | } 172 | } 173 | } 174 | 175 | /// 176 | /// Set scanning state 177 | /// 178 | /// 179 | public void SetScanningState(bool state) 180 | { 181 | Logger.Add("> MEMORY SCANNING: " + (state ? "ON" : "OFF")); 182 | Scanning = state; 183 | 184 | // set the same state on the map view 185 | MapViewer.SetScanningState(state); 186 | } 187 | 188 | 189 | /// 190 | /// Init timer, basically a "delay" 191 | /// 192 | /// 193 | /// 194 | private void InitializeTimer_Tick(object sender, EventArgs e) 195 | { 196 | ActorItem player = GameMemory.GetPlayer(); 197 | 198 | Logger.Add(" "); 199 | Logger.Add($"~ Hello {player.Name}!"); 200 | Logger.Add(" "); 201 | 202 | if (player.MapID == 0) 203 | { 204 | Logger.Add("Oh no, the MapID is 0, either the offsets are broke, you're not logged in, or idk... Ask Vekien."); 205 | Logger.Add("No mapping today"); 206 | SetStatus("/sadface"); 207 | } 208 | 209 | // disable initialize timer, and add memory timer 210 | InitializeTimer.Enabled = false; 211 | Initialized(); 212 | } 213 | 214 | /// 215 | /// Start countdown when zoning, give memory time to init 216 | /// 217 | int zonedTimerCountdownValue = 3; 218 | System.Timers.Timer StartZonedTimer; 219 | public void StartZonedTimerCountdown() 220 | { 221 | Logger.Add("Starting map recording countdown"); 222 | 223 | StartZonedTimer = new System.Timers.Timer(1000) 224 | { 225 | Enabled = true 226 | }; 227 | StartZonedTimer.Elapsed += new ElapsedEventHandler(StartZonedTimerCountdownTick); 228 | StartZonedTimer.Start(); 229 | } 230 | 231 | public void StartZonedTimerCountdownTick(object sender, ElapsedEventArgs e) 232 | { 233 | if (zonedTimerCountdownValue == 0) 234 | { 235 | Logger.Add("Ready to record"); 236 | Logger.Add("================================================"); 237 | MapViewer.SetMapCountdown("Recording"); 238 | 239 | // reset count 240 | zonedTimerCountdownValue = 3; 241 | 242 | // stop timer 243 | StartZonedTimer.Stop(); 244 | 245 | // set scanning state 246 | SetScanningState(true); 247 | } 248 | else 249 | { 250 | string message = $"Starting in: {zonedTimerCountdownValue} ..."; 251 | Logger.Add(message); 252 | MapViewer.SetMapCountdown(message); 253 | zonedTimerCountdownValue--; 254 | } 255 | } 256 | 257 | #endregion 258 | 259 | #region Application Move/Close 260 | 261 | /// 262 | /// Closing the application 263 | /// 264 | /// 265 | /// 266 | private void AppClose(object sender, EventArgs e) 267 | { 268 | MapViewer.Dispose(); 269 | DebugViewer.Dispose(); 270 | Application.Exit(); 271 | } 272 | 273 | /// 274 | /// Setting application focus 275 | /// 276 | /// 277 | /// 278 | private void App_Focused(object sender, EventArgs e) 279 | { 280 | TopMost = Properties.Settings.Default.AlwaysOnTop; 281 | } 282 | 283 | #endregion 284 | 285 | #region Application Status 286 | 287 | /// 288 | /// Set window status 289 | /// 290 | /// 291 | public void SetStatus(string text) 292 | { 293 | labelStatus.Text = text; 294 | } 295 | 296 | #endregion 297 | 298 | #region Application Buttons 299 | 300 | /// 301 | /// Open map 302 | /// 303 | /// 304 | /// 305 | private void BtnOpenMap_Click(object sender, EventArgs e) 306 | { 307 | MapViewer.Show(); 308 | } 309 | 310 | /// 311 | /// Open debug viewer 312 | /// 313 | /// 314 | /// 315 | private void BtnOpenDebug_Click(object sender, EventArgs e) 316 | { 317 | DebugViewer.Show(); 318 | } 319 | 320 | /// 321 | /// Manually submit to API 322 | /// 323 | /// 324 | /// 325 | private void BtnSubmitToApi_Click(object sender, EventArgs e) 326 | { 327 | if (API.IsEnabled()) { 328 | Logger.Add("Manually submitting XIVAPI data ..."); 329 | TrackingEnemies.SubmitData(); 330 | TrackingNpcs.SubmitData(); 331 | return; 332 | } 333 | 334 | Logger.Add("You have not turned on 'Submit to XIVAPI'. Nothing submitted."); 335 | } 336 | 337 | #endregion 338 | 339 | #region Settings 340 | 341 | public void HandleKeyVerification(bool enabled, string username) 342 | { 343 | Settings_Submit.Checked = enabled; 344 | Logger.Add(enabled ? $"XIVAPI Enabled, welcome {username}." : $"XIVAPI Permission Denied."); 345 | } 346 | 347 | private void LoadSettings() 348 | { 349 | TopMost = Properties.Settings.Default.AlwaysOnTop; 350 | Settings_AlwaysOnTop.Checked = Properties.Settings.Default.AlwaysOnTop; 351 | Settings_MapBoundaries.Checked = Properties.Settings.Default.MapBounds; 352 | Settings_IgnoreNoneEnglish.Checked = Properties.Settings.Default.IgnoreNoneEnglish; 353 | Settings_ExtendLogMessages.Checked = Properties.Settings.Default.ExtendLogMessages; 354 | Settings_ScanTimerSpeed.Text = Properties.Settings.Default.ScanTimerSpeed.ToString(); 355 | Settings_MapPlayerTimerSpeed.Text = Properties.Settings.Default.MapPlayerTimerSpeed.ToString(); 356 | Settings_ApiKey.Text = Properties.Settings.Default.ApiKey.ToString(); 357 | Settings_ApiUrl.Text = Properties.Settings.Default.ApiUrl.ToString(); 358 | } 359 | 360 | private void Settings_Submit_CheckedChanged(object sender, EventArgs e) 361 | { 362 | API.ToggleMapSubmissions(); 363 | 364 | if (Settings_Submit.Checked) { 365 | API.CheckApiKey(); 366 | } 367 | } 368 | 369 | private void Settings_AlwaysOnTop_CheckedChanged(object sender, EventArgs e) 370 | { 371 | Properties.Settings.Default.AlwaysOnTop = Settings_AlwaysOnTop.Checked; 372 | Properties.Settings.Default.Save(); 373 | 374 | } 375 | 376 | private void Settings_MapBoundaries_CheckedChanged(object sender, EventArgs e) 377 | { 378 | Properties.Settings.Default.MapBounds = Settings_MapBoundaries.Checked; 379 | Properties.Settings.Default.Save(); 380 | } 381 | 382 | private void Settings_IgnoreNoneEnglish_CheckedChanged(object sender, EventArgs e) 383 | { 384 | Properties.Settings.Default.IgnoreNoneEnglish = Settings_IgnoreNoneEnglish.Checked; 385 | Properties.Settings.Default.Save(); 386 | } 387 | 388 | private void Settings_ExtendLogMessages_CheckedChanged(object sender, EventArgs e) 389 | { 390 | Properties.Settings.Default.ExtendLogMessages = Settings_ExtendLogMessages.Checked; 391 | Properties.Settings.Default.Save(); 392 | } 393 | 394 | private void Settings_ScanTimerSpeed_TextChanged(object sender, EventArgs e) 395 | { 396 | Properties.Settings.Default.ScanTimerSpeed = Int32.Parse(Settings_ScanTimerSpeed.Text); 397 | Properties.Settings.Default.Save(); 398 | } 399 | 400 | private void Settings_MapPlayerTimerSpeed_TextChanged(object sender, EventArgs e) 401 | { 402 | Properties.Settings.Default.MapPlayerTimerSpeed = Int32.Parse(Settings_MapPlayerTimerSpeed.Text); 403 | Properties.Settings.Default.Save(); 404 | } 405 | 406 | private void Settings_ApiKey_TextChanged(object sender, EventArgs e) 407 | { 408 | Properties.Settings.Default.ApiKey = Settings_ApiKey.Text.Trim(); 409 | Properties.Settings.Default.Save(); 410 | } 411 | 412 | private void Settings_ApiUrl_TextChanged(object sender, EventArgs e) 413 | { 414 | Properties.Settings.Default.ApiUrl = Settings_ApiUrl.Text.Trim(); 415 | Properties.Settings.Default.Save(); 416 | } 417 | } 418 | 419 | #endregion 420 | 421 | 422 | } 423 | -------------------------------------------------------------------------------- /Mappy/App.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 19, 18 122 | 123 | 124 | 170, 18 125 | 126 | 127 | 77 128 | 129 | 130 | 131 | 132 | AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA 133 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 134 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 135 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA 136 | AAABAAACAwABEQEAAB8AAAAiAQEAEQAAAAIAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 137 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 138 | AAAAAAAAAAAABAABAB4AAABlFxIGoBUTCp4AAABgAAEAFwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 139 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 140 | AAAAAAAAAAAAAAAAAAQAAQEiAAAAUyggBKyghi7nopFD4yUgC60AAABQAAAAEwAAAAIAAAAAAAAAAAAA 141 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 142 | AAAAAAAAAAAAAAABAQAAAQECAAABHwAAAFUdFwKonXYP6POyHvz2uir8qowp6CQkEKQAAABNAAAAFAAA 143 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 144 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAwABAh0AAAFaHRYApZBmB+7kmgv+5JMC/uqKAP75tRz+sKE07CYs 145 | EqgAAABRAAAAEwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 146 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAgEfAAAAVR8YAqiPZQbs1ocC/diKAP7diQD/5XMA/++D 147 | AP73xBn9oaQ16iIpDaoAAABQAAAAEwAAAAEAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 148 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQAAAgEDAAEAHQAAAFMcFgGojWUE69GIBP3TgAD+z4EA/9eB 149 | AP/aZwD/4WkA/vutAv735x78oKg26R4iEKcAAABQAAAAEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 150 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwABABwAAAFZIBgBp4piA+zQiQP9zIEA/st/ 151 | AP/PgAD/0XsA/81iAP/fZAH/+6MH/v/gA/758yb+p6o76SMmEKgAAABRAAAAFAAAAAEAAAAAAAAAAAAA 152 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAgIcAAAAUh0WAqeMZQXszIYB/cqC 153 | AP7LgAD/zX8A/9CDAP7SfgD/0GUA/99mAP/6qQn//+gU/vzzB/738CX9pJYw6SEgDKgAAABPAAAAEwAA 154 | AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQADAAAAGwAAAFMcFgKojGUE68qG 155 | Av3MgQD+yYAA/8x/AP/QfwD/1IgA/9uHAP/gbwD/7nYA//2+Ff//7yr//fYW/v/fBf74uRX8o4Ql6iIj 156 | DKcAAABRAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAwAAABsAAABXIBgAqohi 157 | BOvNiQP9yoEA/sqAAP/NgQD/zoAA/9OFAP/ckQD/7JcA/vaJAP/8oQP//94j///yMv//8yD//csJ/vmQ 158 | AP74kRD+q3ob6CghCqgAAABRAAAAFQAAAAIAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAIAAAIbAAAAUxoV 159 | BKeOZgnr0YcD/Ml/AP7KgAD/zIAA/86AAP/ShAD/24wA/+qbAP76pwD+/68B///UD///9Sz+//Yw///s 160 | G///vAn/94MD/uNkAP7ieAr8oXAW6CQdB6cAAABOAAAAEwAAAQEAAAEAAAAAAAABAAAAAQACAAAAFgAA 161 | AE8cFgKpkWwO69KKBv3NfwH+x38A/8qAAP/NgAD/0oQA/9mMAP/slwD//KwA///DAv//3Af///MV///6 162 | Jv7/9CP//9EN//2WAv/qbAH/xlMA/sNSAP7RbgX9oW4X6TAjCqMAAABPAAABEgAEAQEAAwIAAAAAAAAA 163 | AA4AAABcIhQAroVaAevSigb+yn4A/sZ+AP/NgQD/0IIA/9WFAP/fjgD/7ZkA/vuqAP//xQD//+AC///z 164 | Av//9gb//+wO/v/MCf/7lgD/6mYA/85KAP+0PwD/qzwA/rlEAP7Vagv+nGAN5ykZAKwAAABQAAAECwAB 165 | DgAAAAsAAAACHwwKAJ+IYxTn2pga/MaEDf7GhAz/yoUM/8+GDP/WjAz/35QN/+6hEP77sRT//8sj///l 166 | PP//+Er///05///xJP//0x3++6kR//CECf/Yagj+vlQI/7FICP+uRAj+rEcH/7RMBf/Nexb7k3Yo4xEQ 167 | B5gAAAIfAAENAAAAAAAAAAMbDgsAkIl6Q+L04Kb88tqs//LXmf/v1ZP/79aX//TanP/33qH//eep/v/w 168 | r///+br///7J////yv///KX//++B///edv/+z2z/98Zn//C+Z//rt2b/6LRl/+u0ZP/qsl7/6K5c/+69 169 | cfmFc0ThCgoEkwAAABsAAgEAAAAAAQAAAwYAAABCHBkRr5WJauv45MT8/OfJ//fmwP/36b//++zI//7y 170 | 0f//+Nj///3d///+4v///uL///7b///1sP//4ov//diE//nRfv/xynr/6sZ6/+fDe//mwnz/4r97/+XA 171 | e//nxYb8jnlX5hoWELAAAABGAAEABgABAAAAAAAAAAABAAAAAQsAAABLGxYJp5aDU+f23rT8/+m+//3p 172 | tv/+7Lr///PG///6z////dP+//7X///+1v//+8f//eeR//nRdP/1ynf/7cVz/+jAcP/lvnD/5L1w/+a9 173 | cf/nvnP/4710+4x2S+QXEg2oAAAATAAAAQoAAAAAAAAAAAAAAAAAAAABAAAAAgAAAQ0AAABKGBMIrJaG 174 | WeX147X6/+3G///vw/7/9cn///vS///81f///dT///3T/v/zvv/414D/8shw/+zFeP/ownX/5sB0/+XA 175 | dP/nwHP/5r9z/+K+dfuLeEzlFRILqgAAAEkAAAAMAgAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAA 176 | AA8AAABMHRkMrZeFWub46Lr7//TQ/v/40P///dX+/vzX///70///983//eu1//TPfP/vxXL/6MJ2/+bA 177 | dP/lv3L/5L1x/+a+cf/iv3j8iHZK5hsYDqwAAABNAAAADQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 178 | AAAAAAAAAAAEAAAAAQ0AAABMHRQIqJeHWeb16b77//vW/v3+1//9+9T//vXN///yyP/65K3/78p5/+rB 179 | cf/lwHP/5L9y/+S+cP/mv3P/3rt0+4p3S+YWEwypAAAASgAAAAsBAAAAAAAAAAAAAAAAAAAAAAAAAAAA 180 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAwAAABMHhkLq5uSYeT388T7//7a///71f7+8sj//u7D//jh 181 | q//qxXn/579x/+XAdP/lv3L/475y/9+8dPuId03lFhMMqwAAAEoAAAAMAwAAAAEAAAAAAAAAAAAAAAAA 182 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAA0AAABMHRwNrJ2YZ+b5+Mj7/frS//7y 183 | yf/97cP/9eGt/+jEe//mvnD/5cB2/+W/c//iv3n8iHdM5hoXDqsAAABMAQAACwAAAAAAAAAAAAAAAAAA 184 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAABLHRwMqJ2b 185 | aOb28cD7//PM/v3tx//547P+6cZ9/+O8bP/mwHf/3r13+4t4S+YXFA2pAAAASgEAAAsEAAAAAAAAAAAA 186 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA 187 | AAwAAABNICERrJ+caeX57b/8/+7N//3ou//xzoP/5r9s/+O/ePyNek/lGBYNqgAAAEwAAAAOAAAAAAAA 188 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 189 | AAAAAAAAAAAAAQAAAA4AAABNHhwOq6Odauj69MX8+Oe///bRif/yy3v8lYFU5hkWDaoAAABOAQAADQIA 190 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 191 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABLIB4Op6Wiceb47cD59t2b+pmCTecaFw+nAAAASgQA 192 | AA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 193 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAQ8AAABNIiMVroyPY+GJhlviHxsPrgAA 194 | AEsAAQAOAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 195 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAwAAABLDhEFlQ0P 196 | BpUAAABLAQIADAEBAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 197 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 198 | AAgAAAAeAAAAHAAAAAYAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 199 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 200 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 201 | AAAAAAAAAAAAAAAAAAAAAAAA///////4H///8A///+AH///AA///gAH//wAA//4AAH/8AAA/+AAAH/AA 202 | AA/gAAAHgAAAA4AAAAGAAAABgAAAAQAAAAEAAAABAAAAAwAAAAGAAAAH4AAAF/AAAB/wAAA//AAA//4A 203 | AP/+AAH//4AD///AA///wA////g///////8= 204 | 205 | 206 | -------------------------------------------------------------------------------- /Mappy/Entities/Entity.cs: -------------------------------------------------------------------------------- 1 | using Sharlayan.Core; 2 | using Mappy.Helpers; 3 | using System; 4 | 5 | namespace Mappy.Entities 6 | { 7 | public class Entity 8 | { 9 | public string Index; 10 | public uint ENpcResidentID; 11 | public uint BNpcNameID; 12 | public uint BNpcBaseID; 13 | public uint ID1; 14 | public uint ID2; 15 | public uint ModelID; // ModelID 16 | public string Name; 17 | public string Type; 18 | public byte TypeID; 19 | public byte Race; 20 | public uint MapID; 21 | public uint MapIndex; 22 | public uint MapTerritoryId; 23 | public uint PlaceNameId; 24 | public double CoordinateX; 25 | public double CoordinateY; 26 | public double CoordinateZ; 27 | public double PosX; 28 | public double PosY; 29 | public int PixelX; 30 | public int PixelY; 31 | public int HPMax; 32 | public int MPMax; 33 | public byte JobID; 34 | public byte Level; 35 | public byte AggroFlags; 36 | public byte CombatFlags; 37 | public uint FateID; 38 | public bool FateSpawned; 39 | public string EventObjectType; 40 | public uint EventObjectTypeID; 41 | public byte GatheringInvisible; 42 | public byte GatheringStatus; 43 | public float HitBoxRadius; 44 | public bool IsGM; 45 | 46 | public Entity(string index, ActorItem entity) 47 | { 48 | dynamic map = App.Instance.MapViewer.Map; 49 | 50 | // Assign dat file ID's to memory ids 51 | if (index == "ENPC") { 52 | ENpcResidentID = entity.NPCID2; 53 | } else { 54 | BNpcNameID = entity.ModelID; 55 | BNpcBaseID = entity.NPCID2; 56 | } 57 | 58 | Index = index; 59 | ID1 = entity.NPCID1; 60 | ID2 = entity.NPCID2; 61 | ModelID = entity.ModelID; 62 | Name = entity.Name.ToString().Trim(); 63 | Type = entity.Type.ToString(); 64 | TypeID = entity.TypeID; 65 | Race = entity.Race; 66 | MapID = entity.MapID; 67 | MapIndex = entity.MapIndex; 68 | MapTerritoryId = entity.MapTerritory; 69 | PlaceNameId = map.PlaceName.ID; 70 | 71 | CoordinateX = Math.Round(entity.Coordinate.X, 6); 72 | CoordinateY = Math.Round(entity.Coordinate.Y, 6); 73 | CoordinateZ = Math.Round(entity.Coordinate.Z, 6); 74 | 75 | PosX = Math.Round(MapHelper.ConvertCoordinatesIntoMapPosition((double)map.SizeFactor, (double)map.OffsetX, entity.Coordinate.X), 6); 76 | PosY = Math.Round(MapHelper.ConvertCoordinatesIntoMapPosition((double)map.SizeFactor, (double)map.OffsetY, entity.Coordinate.Y), 6); 77 | PixelX = MapHelper.ConvertMapPositionToPixels(PosX, (double)map.SizeFactor); 78 | PixelY = MapHelper.ConvertMapPositionToPixels(PosY, (double)map.SizeFactor); 79 | 80 | HPMax = entity.HPMax; 81 | MPMax = entity.MPMax; 82 | Level = entity.Level; 83 | FateID = entity.Fate; 84 | FateSpawned = entity.IsFate; 85 | AggroFlags = entity.AgroFlags; 86 | CombatFlags = entity.CombatFlags; 87 | EventObjectType = entity.EventObjectType.ToString(); 88 | EventObjectTypeID = entity.EventObjectTypeID; 89 | GatheringInvisible = entity.GatheringInvisible; 90 | GatheringStatus = entity.GatheringStatus; 91 | HitBoxRadius = entity.HitBoxRadius; 92 | IsGM = entity.IsGM; 93 | JobID = entity.JobID; 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Mappy/Entities/MapIcon.cs: -------------------------------------------------------------------------------- 1 | using Sharlayan.Core; 2 | using System; 3 | using System.Drawing; 4 | using System.Drawing.Drawing2D; 5 | using Mappy.Helpers; 6 | 7 | namespace Mappy.Entities 8 | { 9 | // Player Icon struct 10 | public struct MapIcon 11 | { 12 | public ActorItem entity; 13 | public Bitmap icon; 14 | public int x, y; 15 | public int id; 16 | public double angle; 17 | public float width, height; 18 | 19 | // 20 | // Set the icons rotation 21 | // 22 | public void setRotation() 23 | { 24 | Bitmap newBitmap = new Bitmap((int)width, (int)height); 25 | Graphics graphics = Graphics.FromImage(newBitmap); 26 | 27 | try { 28 | lock (graphics) 29 | graphics.InterpolationMode = InterpolationMode.Bilinear; 30 | 31 | graphics.TranslateTransform(width / 2, ((float)height / 2)); 32 | graphics.RotateTransform((float)angle); 33 | graphics.TranslateTransform(-width / 2, -((float)height / 2)); 34 | graphics.DrawImage(icon, new Point(0, 0)); 35 | icon = newBitmap; 36 | } 37 | catch (Exception ex) 38 | { 39 | //Logger.Exception(ex, "MapIcon -> SetRotation"); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Mappy/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Mappy/Helpers/AppHelper.cs: -------------------------------------------------------------------------------- 1 | using Sharlayan.Core; 2 | using System; 3 | using System.Drawing; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Security.Cryptography; 8 | using System.Text; 9 | 10 | namespace Mappy.Helpers 11 | { 12 | static class AppHelper 13 | { 14 | /// 15 | /// Get the path to the application 16 | /// 17 | /// 18 | public static string getApplicationPath() 19 | { 20 | string path = Assembly.GetExecutingAssembly().CodeBase; 21 | var directory = Path.GetDirectoryName(path); 22 | return new Uri(directory).LocalPath; 23 | } 24 | 25 | /// 26 | /// Get the current time 27 | /// 28 | /// 29 | public static string getCurrentTime() 30 | { 31 | DateTime now = DateTime.Now; 32 | return now.ToString(Properties.Settings.Default.TimeFormat); 33 | } 34 | 35 | /// 36 | /// Create a fast bitmap of: Format32bppPArgb 37 | /// 38 | /// 39 | /// 40 | public static Bitmap createBitmap(string file) 41 | { 42 | Bitmap orig = new Bitmap(file); 43 | Bitmap clone = new Bitmap(orig.Width, orig.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb); 44 | 45 | using (Graphics gr = Graphics.FromImage(clone)) { 46 | gr.DrawImage(orig, new Rectangle(0, 0, clone.Width, clone.Height)); 47 | } 48 | 49 | orig.Dispose(); 50 | 51 | return clone; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Mappy/Helpers/GameMemory.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using Sharlayan.Models; 5 | using Sharlayan; 6 | using Sharlayan.Core; 7 | using System; 8 | using Sharlayan.Models.ReadResults; 9 | 10 | namespace Mappy.Helpers 11 | { 12 | static class GameMemory 13 | { 14 | /// 15 | /// Set the game process 16 | /// 17 | /// 18 | public static bool SetGameProcess() 19 | { 20 | Logger.Add("Looking for the FFXIV game process (ffxiv_dx11.exe)"); 21 | 22 | Process[] processes = Process.GetProcessesByName("ffxiv_dx11"); 23 | if (processes.Length > 0) { 24 | // supported: English, Chinese, Japanese, French, German, Korean 25 | string gameLanguage = "English"; 26 | 27 | // whether to always hit API on start to get the latest sigs based on patchVersion, or use the local json cache (if the file doesn't exist, API will be hit) 28 | bool useLocalCache = true; 29 | 30 | // patchVersion of game, or latest 31 | string patchVersion = "latest"; 32 | Process process = processes[0]; 33 | ProcessModel processModel = new ProcessModel 34 | { 35 | Process = process, 36 | IsWin64 = true 37 | }; 38 | MemoryHandler.Instance.SetProcess(processModel, gameLanguage, patchVersion, useLocalCache); 39 | 40 | Logger.Add("--> Hooked into ffxiv_dx11.exe"); 41 | return true; 42 | } 43 | 44 | Logger.Add("! Could not find the FFXIV Game, please make sure you're on DX11 (dx9 dead)"); 45 | return false; 46 | } 47 | 48 | /// 49 | /// Get the current player actor 50 | /// 51 | /// 52 | public static ActorItem GetPlayer() 53 | { 54 | Reader.GetActors(); 55 | return ActorItem.CurrentUser; 56 | } 57 | 58 | /// 59 | /// Get the current target actor 60 | /// 61 | /// 62 | public static ActorItem GetCurrentTarget() 63 | { 64 | try 65 | { 66 | TargetResult readResult = Reader.GetTargetInfo(); 67 | return readResult.TargetInfo.CurrentTarget; 68 | } 69 | catch (Exception ex) 70 | { 71 | Logger.Exception(ex, "GameMemory -> GetCurrentTarget"); 72 | } 73 | 74 | return GetPlayer(); 75 | } 76 | 77 | /// 78 | /// Get all monsters around the player in memory 79 | /// 80 | /// 81 | public static List GetMonstersAroundPlayer() 82 | { 83 | ActorResult readResult = Reader.GetActors(); 84 | return readResult.CurrentMonsters.Select(e => e.Value).ToList(); 85 | } 86 | 87 | /// 88 | /// Get all npcs around the player in memory 89 | /// 90 | /// 91 | public static List GetNpcsAroundPlayer() 92 | { 93 | ActorResult readResult = Reader.GetActors(); 94 | return readResult.CurrentNPCs.Select(e => e.Value).ToList(); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Mappy/Helpers/Logger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Linq; 6 | 7 | namespace Mappy.Helpers 8 | { 9 | static class Logger 10 | { 11 | private static List logs = new List(); 12 | private static List lines = new List(); 13 | 14 | // 15 | // Add to log 16 | // 17 | public static void Add(string text) 18 | { 19 | // create log entry 20 | text = String.Format("[{0}] {1}", AppHelper.getCurrentTime(), text); 21 | 22 | // add to lists 23 | logs.Add(text); 24 | lines.Add(text); 25 | 26 | // save every 50 lines 27 | if (lines.Count > 25) 28 | { 29 | try { 30 | // generate log lines 31 | string loglines = String.Join(Environment.NewLine, lines.ToArray()); 32 | 33 | // clear logs 34 | lines.Clear(); 35 | 36 | // write to log 37 | File.AppendAllText(GetLogFilename(), loglines + Environment.NewLine); 38 | } 39 | catch (Exception err) 40 | { 41 | Add("-- Could not write to log file: " + err.Message); 42 | } 43 | } 44 | } 45 | 46 | public static void Exception(Exception ex, string message) 47 | { 48 | var LineNumber = new StackTrace(ex, true).GetFrame(0).GetFileLineNumber(); 49 | 50 | Add("---[ EXCEPTION ]------------------------------------------------"); 51 | Add($"{LineNumber} :: {message}"); 52 | Add(ex.ToString()); 53 | Add("----------------------------------------------------------------"); 54 | } 55 | 56 | public static void Write(string filename, string text) 57 | { 58 | text = String.Format("[{0}] {1}", AppHelper.getCurrentTime(), text); 59 | File.AppendAllText(AppHelper.getApplicationPath() + "/logs/" + filename, text + Environment.NewLine); 60 | } 61 | 62 | // 63 | // Get log entries 64 | // 65 | public static List Get(int skipCount) 66 | { 67 | List copy = logs; 68 | copy = copy.Skip(skipCount).ToList(); 69 | return copy; 70 | } 71 | 72 | // 73 | // Reset log entries 74 | // 75 | public static void Geset() 76 | { 77 | File.WriteAllText(GetLogFilename(), String.Empty); 78 | } 79 | 80 | // 81 | // Get log filename 82 | // 83 | private static string GetLogFilename() 84 | { 85 | if (!Directory.Exists(AppHelper.getApplicationPath() + "/logs/")) 86 | { 87 | Directory.CreateDirectory(AppHelper.getApplicationPath() + "/logs/"); 88 | } 89 | 90 | // get log file 91 | return AppHelper.getApplicationPath() + "/logs/log.txt"; 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Mappy/Helpers/MapHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Mappy.Helpers 4 | { 5 | public static class MapHelper 6 | { 7 | // 8 | // Using ingame coordinate to map position in pixels 9 | // 10 | public static double ConvertCoordinatesIntoMapPosition(double scale, double offset, double val) 11 | { 12 | val = Math.Round(val, 3); 13 | val = (val + offset) * scale; 14 | return ((41.0 / scale) * ((val + 1024.0) / 2048.0)) + 1; 15 | } 16 | 17 | // 18 | // Convert map position to pixels 19 | // 20 | public static int ConvertMapPositionToPixels(double value, double scale) 21 | { 22 | return Convert.ToInt32((value - 1) * 50 * scale); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Mappy/MapViewer.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Mappy 2 | { 3 | partial class MapViewer 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MapViewer)); 33 | this.mapvisual = new System.Windows.Forms.PictureBox(); 34 | this.UpdateTicker = new System.Windows.Forms.Timer(this.components); 35 | this.mapstatus = new System.Windows.Forms.Label(); 36 | this.mapinfo = new System.Windows.Forms.Label(); 37 | this.mappos = new System.Windows.Forms.Label(); 38 | this.mapCountdown = new System.Windows.Forms.Label(); 39 | ((System.ComponentModel.ISupportInitialize)(this.mapvisual)).BeginInit(); 40 | this.SuspendLayout(); 41 | // 42 | // mapvisual 43 | // 44 | this.mapvisual.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 45 | | System.Windows.Forms.AnchorStyles.Left) 46 | | System.Windows.Forms.AnchorStyles.Right))); 47 | this.mapvisual.BackColor = System.Drawing.Color.Transparent; 48 | this.mapvisual.InitialImage = null; 49 | this.mapvisual.Location = new System.Drawing.Point(0, 0); 50 | this.mapvisual.Name = "mapvisual"; 51 | this.mapvisual.Size = new System.Drawing.Size(752, 567); 52 | this.mapvisual.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; 53 | this.mapvisual.TabIndex = 0; 54 | this.mapvisual.TabStop = false; 55 | this.mapvisual.Paint += new System.Windows.Forms.PaintEventHandler(this.VisualPaint); 56 | this.mapvisual.MouseDown += new System.Windows.Forms.MouseEventHandler(this.VisualMouseDown); 57 | this.mapvisual.MouseMove += new System.Windows.Forms.MouseEventHandler(this.VisualMouseMove); 58 | // 59 | // UpdateTicker 60 | // 61 | this.UpdateTicker.Enabled = true; 62 | this.UpdateTicker.Interval = 1000; 63 | this.UpdateTicker.Tick += new System.EventHandler(this.UpdateTicker_Tick); 64 | // 65 | // mapstatus 66 | // 67 | this.mapstatus.AutoSize = true; 68 | this.mapstatus.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(35)))), ((int)(((byte)(35)))), ((int)(((byte)(35))))); 69 | this.mapstatus.Font = new System.Drawing.Font("Segoe UI Semibold", 10F); 70 | this.mapstatus.ForeColor = System.Drawing.Color.White; 71 | this.mapstatus.Location = new System.Drawing.Point(0, 0); 72 | this.mapstatus.Name = "mapstatus"; 73 | this.mapstatus.Padding = new System.Windows.Forms.Padding(5, 3, 5, 5); 74 | this.mapstatus.Size = new System.Drawing.Size(107, 31); 75 | this.mapstatus.TabIndex = 0; 76 | this.mapstatus.Text = "Map Status"; 77 | this.mapstatus.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; 78 | // 79 | // mapinfo 80 | // 81 | this.mapinfo.AutoSize = true; 82 | this.mapinfo.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(35)))), ((int)(((byte)(35)))), ((int)(((byte)(35))))); 83 | this.mapinfo.Font = new System.Drawing.Font("Segoe UI Semibold", 10F); 84 | this.mapinfo.ForeColor = System.Drawing.Color.White; 85 | this.mapinfo.Location = new System.Drawing.Point(0, 27); 86 | this.mapinfo.Name = "mapinfo"; 87 | this.mapinfo.Padding = new System.Windows.Forms.Padding(5, 3, 5, 5); 88 | this.mapinfo.Size = new System.Drawing.Size(91, 31); 89 | this.mapinfo.TabIndex = 2; 90 | this.mapinfo.Text = "Map Info"; 91 | this.mapinfo.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; 92 | // 93 | // mappos 94 | // 95 | this.mappos.AutoSize = true; 96 | this.mappos.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(35)))), ((int)(((byte)(35)))), ((int)(((byte)(35))))); 97 | this.mappos.Font = new System.Drawing.Font("Segoe UI Semibold", 10F); 98 | this.mappos.ForeColor = System.Drawing.Color.White; 99 | this.mappos.Location = new System.Drawing.Point(0, 54); 100 | this.mappos.Name = "mappos"; 101 | this.mappos.Padding = new System.Windows.Forms.Padding(5, 3, 5, 5); 102 | this.mappos.Size = new System.Drawing.Size(120, 31); 103 | this.mappos.TabIndex = 4; 104 | this.mappos.Text = "Map Position"; 105 | this.mappos.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; 106 | // 107 | // mapCountdown 108 | // 109 | this.mapCountdown.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 110 | this.mapCountdown.AutoSize = true; 111 | this.mapCountdown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(35)))), ((int)(((byte)(35)))), ((int)(((byte)(35))))); 112 | this.mapCountdown.Font = new System.Drawing.Font("Segoe UI Semibold", 10F); 113 | this.mapCountdown.ForeColor = System.Drawing.Color.White; 114 | this.mapCountdown.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; 115 | this.mapCountdown.Location = new System.Drawing.Point(0, 540); 116 | this.mapCountdown.Name = "mapCountdown"; 117 | this.mapCountdown.Padding = new System.Windows.Forms.Padding(5, 3, 5, 5); 118 | this.mapCountdown.Size = new System.Drawing.Size(27, 31); 119 | this.mapCountdown.TabIndex = 5; 120 | this.mapCountdown.Text = "-"; 121 | this.mapCountdown.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; 122 | // 123 | // MapViewer 124 | // 125 | this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 21F); 126 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 127 | this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(120)))), ((int)(((byte)(120)))), ((int)(((byte)(120))))); 128 | this.ClientSize = new System.Drawing.Size(752, 567); 129 | this.Controls.Add(this.mapCountdown); 130 | this.Controls.Add(this.mappos); 131 | this.Controls.Add(this.mapinfo); 132 | this.Controls.Add(this.mapstatus); 133 | this.Controls.Add(this.mapvisual); 134 | this.Font = new System.Drawing.Font("Segoe UI Semibold", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 135 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 136 | this.Margin = new System.Windows.Forms.Padding(4); 137 | this.Name = "MapViewer"; 138 | this.Text = "MAP - FINAL FANTASY XIV MAPPY"; 139 | this.Activated += new System.EventHandler(this.MapViewer_Focused); 140 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MapViewer_Closing); 141 | this.Load += new System.EventHandler(this.MapViewer_Load); 142 | ((System.ComponentModel.ISupportInitialize)(this.mapvisual)).EndInit(); 143 | this.ResumeLayout(false); 144 | this.PerformLayout(); 145 | 146 | } 147 | 148 | #endregion 149 | 150 | private System.Windows.Forms.PictureBox mapvisual; 151 | private System.Windows.Forms.Timer UpdateTicker; 152 | private System.Windows.Forms.Label mapstatus; 153 | private System.Windows.Forms.Label mapinfo; 154 | private System.Windows.Forms.Label mappos; 155 | private System.Windows.Forms.Label mapCountdown; 156 | } 157 | } -------------------------------------------------------------------------------- /Mappy/MapViewer.cs: -------------------------------------------------------------------------------- 1 | using Sharlayan.Core; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Drawing; 5 | using System.Drawing.Drawing2D; 6 | using System.Linq; 7 | using System.Windows.Forms; 8 | using Mappy.Entities; 9 | using Mappy.Helpers; 10 | 11 | namespace Mappy 12 | { 13 | public partial class MapViewer : Form 14 | { 15 | // Map Icons 16 | private MapIcon MapPlayer; 17 | private ActorItem player; 18 | private List MapTrail = new List(); 19 | private List MapTrailMini = new List(); 20 | private List MapIcons = new List(); 21 | 22 | private List xPositions = new List(); 23 | private List yPositions = new List(); 24 | private List MarkerIds = new List(); 25 | private int SelectedMarker = 0; 26 | 27 | // Random Variables 28 | public dynamic Map; 29 | public Bitmap MapBackground = null; 30 | public bool Scanning = false; 31 | 32 | // init 33 | public MapViewer() 34 | { 35 | InitializeComponent(); 36 | MapBackground = new Bitmap("assets\\map_default.png"); 37 | } 38 | 39 | public void SetMapCountdown(string text) 40 | { 41 | mapCountdown.Text = text; 42 | } 43 | 44 | // 45 | // Player position update 46 | // 47 | private void UpdateTicker_Tick(object sender, EventArgs e) 48 | { 49 | UpdateTicker.Enabled = false; 50 | InitializeTimer(); 51 | } 52 | 53 | private void InitializeTimer() 54 | { 55 | // create timer 56 | System.Timers.Timer aTimer = new System.Timers.Timer(); 57 | aTimer.Elapsed += (sender, e) => { 58 | if (Scanning) 59 | { 60 | SetPlayerPosition(); 61 | mapvisual.Invalidate(); 62 | } 63 | }; 64 | aTimer.Interval = Properties.Settings.Default.MapPlayerTimerSpeed; 65 | aTimer.Enabled = true; 66 | } 67 | 68 | // 69 | // set player position 70 | // 71 | private void SetPlayerPosition() 72 | { 73 | if (!Scanning) { 74 | return; 75 | } 76 | 77 | player = GameMemory.GetPlayer(); 78 | if (player.Name.Length > 0 && (int)Map.ID > 0) { 79 | SetPlayerIcon(player); 80 | 81 | try 82 | { 83 | double x = Math.Round(MapHelper.ConvertCoordinatesIntoMapPosition((double)Map.SizeFactor, (double)Map.OffsetX, player.X), 2); 84 | double y = Math.Round(MapHelper.ConvertCoordinatesIntoMapPosition((double)Map.SizeFactor, (double)Map.OffsetY, player.Y), 2); 85 | 86 | // set map pos 87 | mappos.Text = String.Format("x {0} / y {1} - [{2} / {3}] - [OX: {4} / OY: {5}]", 88 | x, y, player.X, player.Y, Map.OffsetX, Map.OffsetY 89 | ); 90 | } 91 | catch { } 92 | } 93 | } 94 | 95 | // 96 | // Set scanning state, disabled if querying 97 | // 98 | public void SetScanningState(bool state) 99 | { 100 | Scanning = state; 101 | } 102 | 103 | // 104 | // Set the map image 105 | // 106 | public void SetMapVisual(dynamic newMap) 107 | { 108 | try 109 | { 110 | // clear icons 111 | ClearMapIcons(); 112 | 113 | // set map 114 | Map = newMap; 115 | string hightRestricted = (int)Map.LayerCount > 1 ? "Height Axis Restricted" : "Height Axis Tracking Unrestricted"; 116 | 117 | // apply downloaded map to background 118 | Logger.Add($"Loading map: {Map.LocalFilename}"); 119 | MapBackground = AppHelper.createBitmap((string)Map.LocalFilename); 120 | 121 | // set map status 122 | mapstatus.Text = String.Format("#{0} - {1} - {2} - {3} (Layers: {4} - {5})", 123 | Map.ID, Map.PlaceNameRegion.Name, Map.PlaceName.Name, Map.TerritoryType.PlaceNameZone.Name, Map.LayerCount, hightRestricted 124 | ); 125 | 126 | // set map info 127 | mapinfo.Text = String.Format("{0} - Marker Range {1} - Scale {2} - Territory ID {3}", 128 | Map.LocalFilename, Map.MapMarkerRange, Map.SizeFactor, Map.TerritoryType.ID 129 | ); 130 | 131 | // update status 132 | App.Instance.SetStatus($"Currently mapping: #{Map.ID} - {Map.PlaceName.Name} - {Map.TerritoryType.PlaceNameZone.Name} - {hightRestricted}"); 133 | } 134 | catch (Exception ex) 135 | { 136 | Logger.Exception(ex, "MapViewer -> setMapVisual"); 137 | } 138 | } 139 | 140 | /// 141 | /// Request the latest map 142 | /// 143 | public void RequestLatestMap() 144 | { 145 | // show loading 146 | uint MapId = GameMemory.GetPlayer().MapID; 147 | API.GetMapImage(MapId); 148 | } 149 | 150 | #region Auto-gen 151 | 152 | private void MapViewer_Load(object sender, EventArgs e) 153 | { 154 | TopMost = Properties.Settings.Default.AlwaysOnTop; 155 | } 156 | 157 | private void MapViewer_Closing(object sender, FormClosingEventArgs e) 158 | { 159 | Hide(); 160 | e.Cancel = true; 161 | } 162 | 163 | private void MapViewer_Focused(object sender, EventArgs e) 164 | { 165 | TopMost = Properties.Settings.Default.AlwaysOnTop; 166 | } 167 | 168 | #endregion 169 | 170 | #region Icons! 171 | 172 | /// 173 | /// Set the player icon on the map 174 | /// 175 | /// 176 | private void SetPlayerIcon(ActorItem player) 177 | { 178 | // convert to game positions 179 | double x = MapHelper.ConvertCoordinatesIntoMapPosition((double)Map.SizeFactor, (double)Map.OffsetX, player.Coordinate.X); 180 | double y = MapHelper.ConvertCoordinatesIntoMapPosition((double)Map.SizeFactor, (double)Map.OffsetY, player.Coordinate.Y); 181 | 182 | // check if a player icon already exists or not 183 | if (MapPlayer.id == 0) 184 | { 185 | // Create new player icon bitmap 186 | MapPlayer = new MapIcon 187 | { 188 | id = 1 189 | }; 190 | } 191 | 192 | // reset graphic 193 | Bitmap bitmap = AppHelper.createBitmap("assets\\player.png"); 194 | MapPlayer.icon = bitmap; 195 | MapPlayer.width = bitmap.Width; 196 | MapPlayer.height = bitmap.Height; 197 | 198 | // work out pixel position 199 | int pixelX = Convert.ToInt32((x - 1) * 50 * (double)Map.SizeFactor) - (MapPlayer.icon.Size.Width / 2); 200 | int pixelY = Convert.ToInt32((y - 1) * 50 * (double)Map.SizeFactor) - (MapPlayer.icon.Size.Height / 2); 201 | 202 | // set position and direction 203 | MapPlayer.x = pixelX; 204 | MapPlayer.y = pixelY; 205 | MapPlayer.angle = Math.Abs(player.Heading * (180 / Math.PI) - 180); 206 | MapPlayer.setRotation(); 207 | 208 | // add trail, this is done by just dividing the pixel 209 | 210 | int trailDistance = 120; 211 | int trailDistanceMax = 200; 212 | int xDistance = 0; 213 | int yDistance = 0; 214 | 215 | if (MapTrail.Count > 0) 216 | { 217 | xDistance = Math.Abs(MapTrail[MapTrail.Count - 1].x - pixelX); 218 | yDistance = Math.Abs(MapTrail[MapTrail.Count - 1].y - pixelY); 219 | } 220 | 221 | // if map trail empty or either x or y distance traved is above 100, draw new trail 222 | if (MapTrail.Count == 0 || (xDistance > trailDistance || yDistance > trailDistance)) 223 | { 224 | MapIcon MapTrailIcon = new MapIcon 225 | { 226 | icon = AppHelper.createBitmap("assets\\trail.png"), 227 | id = (MapTrail.Count + 1), 228 | x = pixelX, 229 | y = pixelY, 230 | angle = 0 231 | }; 232 | 233 | MapTrail.Add(MapTrailIcon); 234 | 235 | // set trail sizes 236 | MapTrailSizeWidth = MapTrailIcon.icon.Width; 237 | MapTrailSizeHeight = MapTrailIcon.icon.Height; 238 | } 239 | 240 | // work out pixel position 241 | pixelX = Convert.ToInt32((x - 1) * 50 * (double)Map.SizeFactor) - 10; 242 | pixelY = Convert.ToInt32((y - 1) * 50 * (double)Map.SizeFactor) - 10; 243 | 244 | trailDistance = 20; 245 | trailDistanceMax = 35; 246 | xDistance = 0; 247 | yDistance = 0; 248 | 249 | if (MapTrailMini.Count > 0) 250 | { 251 | xDistance = Math.Abs(MapTrailMini[MapTrailMini.Count - 1].x - pixelX); 252 | yDistance = Math.Abs(MapTrailMini[MapTrailMini.Count - 1].y - pixelY); 253 | } 254 | 255 | // if map trail empty or either x or y distance traved is above 100, draw new trail 256 | if (MapTrailMini.Count == 0 || (xDistance > trailDistance || yDistance > trailDistance)) 257 | { 258 | // Ignore big jumps 259 | if (xDistance > trailDistanceMax || yDistance > trailDistanceMax) 260 | { 261 | return; 262 | } 263 | 264 | xPositions.Add(pixelX); 265 | yPositions.Add(pixelY); 266 | 267 | MapIcon MapTrailMiniIcon = new MapIcon 268 | { 269 | icon = AppHelper.createBitmap("assets\\trailmini.png"), 270 | id = (MapTrailMini.Count + 1), 271 | x = pixelX, 272 | y = pixelY, 273 | angle = 0 274 | }; 275 | 276 | MapTrailMini.Add(MapTrailMiniIcon); 277 | 278 | // set trail sizes 279 | MapTrailMiniSizeWidth = MapTrailMiniIcon.icon.Width; 280 | MapTrailMiniSizeHeight = MapTrailMiniIcon.icon.Height; 281 | } 282 | } 283 | 284 | /// 285 | /// Add a enemy icon to the map 286 | /// 287 | /// 288 | public void AddEnemyIcon(ActorItem entity) 289 | { 290 | string file = "assets\\enemy.png"; 291 | AddIcon(entity, file); 292 | } 293 | 294 | /// 295 | /// Add an NPC icon to the map 296 | /// 297 | /// 298 | public void AddNpcIcon(ActorItem entity) 299 | { 300 | string file = "assets\\npc.png"; 301 | if (entity.Type.ToString() == "Gathering") 302 | { 303 | file = "assets\\gathering.png"; 304 | } 305 | else if (entity.Type.ToString() == "EObj") 306 | { 307 | file = "assets\\object.png"; 308 | } 309 | else if (entity.Type.ToString() == "Unknown") 310 | { 311 | file = "assets\\unknown.png"; 312 | } 313 | 314 | AddIcon(entity, file); 315 | } 316 | 317 | /// 318 | /// Add an icon to the map 319 | /// 320 | /// 321 | /// 322 | private void AddIcon(ActorItem entity, string iconfile) 323 | { 324 | try 325 | { 326 | if ((double)Map.SizeFactor == 0) { 327 | return; 328 | } 329 | 330 | // convert to game entity 331 | double x = MapHelper.ConvertCoordinatesIntoMapPosition((double)Map.SizeFactor, (double)Map.OffsetX, entity.Coordinate.X); 332 | double y = MapHelper.ConvertCoordinatesIntoMapPosition((double)Map.SizeFactor, (double)Map.OffsetY, entity.Coordinate.Y); 333 | 334 | // if positionscome back nothing, skip 335 | if (x == 0 || y == 0) { 336 | return; 337 | } 338 | 339 | // create bitmap 340 | Bitmap bitmap = AppHelper.createBitmap(iconfile); 341 | MapIcon MapIcon = new MapIcon 342 | { 343 | entity = entity, 344 | icon = bitmap, 345 | id = (MapIcons.Count + 1), 346 | width = bitmap.Width, 347 | height = bitmap.Height 348 | }; 349 | 350 | // work out pixel position 351 | double pixelX = Math.Round(((x - 1) * 50 * (double)Map.SizeFactor) - 16, 6); 352 | double pixelY = Math.Round(((y - 1) * 50 * (double)Map.SizeFactor) - 16, 6); 353 | 354 | if (pixelX == 0 || pixelY == 0) { 355 | return; 356 | } 357 | 358 | MapIcon.x = Convert.ToInt32(pixelX); 359 | MapIcon.y = Convert.ToInt32(pixelY); 360 | MapIcons.Add(MapIcon); 361 | } 362 | catch (Exception ex) 363 | { 364 | Logger.Exception(ex, "MapViewer -> addIcon"); 365 | } 366 | } 367 | 368 | /// 369 | /// Clear map icons 370 | /// 371 | private void ClearMapIcons() 372 | { 373 | // clear icons 374 | MapIcons.Clear(); 375 | MapTrail.Clear(); 376 | MapTrailMini.Clear(); 377 | xPositions.Clear(); 378 | yPositions.Clear(); 379 | 380 | // clear list 381 | MarkerIds.Clear(); 382 | SelectedMarker = 0; 383 | } 384 | 385 | #endregion 386 | 387 | #region Map Movement 388 | 389 | // 390 | // Drag the map 391 | // 392 | private int offsetX = 0, offsetY = 0; 393 | private int oldX, oldY; 394 | private int playerpos = 0; 395 | private bool mousemovement = false; 396 | 397 | private void VisualMouseDown(object sender, MouseEventArgs e) 398 | { 399 | mousemovement = true; 400 | 401 | if (MapPlayer.id == 1) { 402 | playerpos = MapPlayer.x + MapPlayer.y; 403 | } 404 | } 405 | 406 | private void VisualMouseMove(object sender, MouseEventArgs e) 407 | { 408 | if (e.Button == MouseButtons.Left) 409 | { 410 | offsetX += e.X - oldX; 411 | offsetY += e.Y - oldY; 412 | } 413 | 414 | // prevent out of bounds 415 | if (Properties.Settings.Default.MapBounds) 416 | { 417 | int y = mapvisual.Size.Height - MapBackground.Size.Height; 418 | int x = mapvisual.Size.Width - MapBackground.Size.Width; 419 | int boundOffset = 0; 420 | 421 | if (offsetY < (y - boundOffset)) 422 | { 423 | offsetY = (y - boundOffset); 424 | } 425 | if (offsetX < (x - boundOffset)) 426 | { 427 | offsetX = (x - boundOffset); 428 | } 429 | 430 | if (offsetX > (0 + boundOffset)) 431 | { 432 | offsetX = (0 + boundOffset); 433 | } 434 | if (offsetY > (0 + boundOffset)) 435 | { 436 | offsetY = (0 + boundOffset); 437 | } 438 | } 439 | 440 | oldX = e.X; 441 | oldY = e.Y; 442 | 443 | mapvisual.Invalidate(); 444 | } 445 | 446 | // 447 | // Draw graphics 448 | // 449 | int MapPlayerIconSizeWidth = 0, 450 | MapPlayerIconSizeHeight = 0, 451 | MapTrailSizeWidth = 0, 452 | MapTrailSizeHeight = 0, 453 | MapTrailMiniSizeWidth = 0, 454 | MapTrailMiniSizeHeight = 0; 455 | 456 | private void VisualPaint(object sender, PaintEventArgs e) 457 | { 458 | // draw the map at the new position 459 | e.Graphics.CompositingMode = CompositingMode.SourceOver; 460 | e.Graphics.InterpolationMode = InterpolationMode.Bilinear; 461 | 462 | if ((MapPlayer.x + MapPlayer.y) != playerpos) { 463 | mousemovement = false; 464 | } 465 | 466 | if (!mousemovement && MapPlayer.id == 1) 467 | { 468 | if (MapPlayerIconSizeWidth == 0) 469 | { 470 | MapPlayerIconSizeWidth = MapPlayer.icon.Size.Width; 471 | MapPlayerIconSizeHeight = MapPlayer.icon.Size.Height; 472 | } 473 | 474 | // ClientRectangle.Width 475 | offsetX = 0 - (MapPlayer.x + (MapPlayerIconSizeWidth / 2)) + ((ClientRectangle.Width) / 2); 476 | offsetY = 0 - (MapPlayer.y + (MapPlayerIconSizeHeight / 2)) + (ClientRectangle.Height / 2); 477 | } 478 | 479 | try 480 | { 481 | lock (MapBackground) 482 | e.Graphics.DrawImage(MapBackground, offsetX, offsetY, MapBackground.Size.Width, MapBackground.Size.Height); 483 | } catch { } 484 | 485 | // add trails 486 | if (MapTrail.Count > 0) 487 | { 488 | try 489 | { 490 | foreach (MapIcon icon in MapTrail) 491 | { 492 | // get new position 493 | int new_x = icon.x + offsetX; 494 | int new_y = icon.y + offsetY; 495 | 496 | // draw player icon 497 | lock (icon.icon) 498 | e.Graphics.DrawImage(icon.icon, new_x, new_y, MapTrailSizeWidth, MapTrailSizeHeight); 499 | } 500 | } 501 | catch { } 502 | } 503 | 504 | // add mini trails 505 | if (MapTrailMini.Count > 0) 506 | { 507 | // only show line when more than 1 entry (need a previous entry) 508 | if (xPositions.Count > 2) 509 | { 510 | try 511 | { 512 | for (int i = 1; i < xPositions.Count; i++) 513 | { 514 | int newX = xPositions[i] + offsetX + (MapTrailMiniSizeWidth / 2), 515 | newY = yPositions[i] + offsetY + (MapTrailMiniSizeHeight / 2), 516 | oldX = xPositions[i - 1] + offsetX + (MapTrailMiniSizeWidth / 2), 517 | oldY = yPositions[i - 1] + offsetY + (MapTrailMiniSizeHeight / 2); 518 | 519 | Pen myPen = new Pen(Color.DodgerBlue) 520 | { 521 | Width = 3 522 | }; 523 | 524 | e.Graphics.DrawLine(myPen, newX, newY, oldX, oldY); 525 | 526 | } 527 | } 528 | catch { } 529 | } 530 | 531 | // print mini map trail, blue dots 532 | try 533 | { 534 | foreach (MapIcon icon in MapTrailMini) 535 | { 536 | // get new position 537 | int new_x = icon.x + offsetX; 538 | int new_y = icon.y + offsetY; 539 | 540 | // draw player icon 541 | lock (icon.icon) 542 | e.Graphics.DrawImage(icon.icon, new_x, new_y, MapTrailMiniSizeWidth, MapTrailMiniSizeHeight); 543 | } 544 | } 545 | catch { } 546 | } 547 | 548 | // if player icon set 549 | if (MapPlayer.id == 1) 550 | { 551 | try 552 | { 553 | // get new position 554 | int new_x = MapPlayer.x + offsetX; 555 | int new_y = MapPlayer.y + offsetY; 556 | 557 | // draw player icon 558 | lock (MapPlayer.icon) 559 | e.Graphics.DrawImage(MapPlayer.icon, new_x, new_y, MapPlayerIconSizeWidth, MapPlayerIconSizeHeight); 560 | } catch { } 561 | } 562 | 563 | // if map icons 564 | if (MapIcons.Count > 0) 565 | { 566 | try { 567 | foreach (MapIcon icon in MapIcons) 568 | { 569 | // get new position 570 | int new_x = icon.x + offsetX; 571 | int new_y = icon.y + offsetY; 572 | 573 | // draw player icon 574 | lock(icon.icon) 575 | e.Graphics.DrawImage(icon.icon, new_x, new_y, icon.icon.Size.Width, icon.icon.Size.Height); 576 | 577 | // highlight selected icon 578 | if (SelectedMarker == icon.id) 579 | { 580 | // draw highlight graphic 581 | Bitmap highlight = new Bitmap("assets\\highlight.png"); 582 | lock(highlight) 583 | e.Graphics.DrawImage(highlight, new_x, new_y, highlight.Size.Width, highlight.Size.Height); 584 | 585 | // add name 586 | Font stringFont = new Font("Verdana", 10, FontStyle.Bold); 587 | e.Graphics.DrawString(icon.entity.Name, stringFont, Brushes.Black, new_x + 36, new_y + 6); 588 | } 589 | } 590 | } 591 | catch (Exception ex) 592 | { 593 | //Logger.Exception(ex, "MapViewer -> VisualPaint"); 594 | } 595 | } 596 | } 597 | 598 | #endregion 599 | } 600 | } 601 | -------------------------------------------------------------------------------- /Mappy/MapViewer.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | 125 | 126 | AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA 127 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 128 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 129 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA 130 | AAABAAACAwABEQEAAB8AAAAiAQEAEQAAAAIAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 131 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 132 | AAAAAAAAAAAABAABAB4AAABlFxIGoBUTCp4AAABgAAEAFwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 133 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 134 | AAAAAAAAAAAAAAAAAAQAAQEiAAAAUyggBKyghi7nopFD4yUgC60AAABQAAAAEwAAAAIAAAAAAAAAAAAA 135 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 136 | AAAAAAAAAAAAAAABAQAAAQECAAABHwAAAFUdFwKonXYP6POyHvz2uir8qowp6CQkEKQAAABNAAAAFAAA 137 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 138 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAwABAh0AAAFaHRYApZBmB+7kmgv+5JMC/uqKAP75tRz+sKE07CYs 139 | EqgAAABRAAAAEwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 140 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAgEfAAAAVR8YAqiPZQbs1ocC/diKAP7diQD/5XMA/++D 141 | AP73xBn9oaQ16iIpDaoAAABQAAAAEwAAAAEAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 142 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQAAAgEDAAEAHQAAAFMcFgGojWUE69GIBP3TgAD+z4EA/9eB 143 | AP/aZwD/4WkA/vutAv735x78oKg26R4iEKcAAABQAAAAEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 144 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwABABwAAAFZIBgBp4piA+zQiQP9zIEA/st/ 145 | AP/PgAD/0XsA/81iAP/fZAH/+6MH/v/gA/758yb+p6o76SMmEKgAAABRAAAAFAAAAAEAAAAAAAAAAAAA 146 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAgIcAAAAUh0WAqeMZQXszIYB/cqC 147 | AP7LgAD/zX8A/9CDAP7SfgD/0GUA/99mAP/6qQn//+gU/vzzB/738CX9pJYw6SEgDKgAAABPAAAAEwAA 148 | AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQADAAAAGwAAAFMcFgKojGUE68qG 149 | Av3MgQD+yYAA/8x/AP/QfwD/1IgA/9uHAP/gbwD/7nYA//2+Ff//7yr//fYW/v/fBf74uRX8o4Ql6iIj 150 | DKcAAABRAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAwAAABsAAABXIBgAqohi 151 | BOvNiQP9yoEA/sqAAP/NgQD/zoAA/9OFAP/ckQD/7JcA/vaJAP/8oQP//94j///yMv//8yD//csJ/vmQ 152 | AP74kRD+q3ob6CghCqgAAABRAAAAFQAAAAIAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAIAAAIbAAAAUxoV 153 | BKeOZgnr0YcD/Ml/AP7KgAD/zIAA/86AAP/ShAD/24wA/+qbAP76pwD+/68B///UD///9Sz+//Yw///s 154 | G///vAn/94MD/uNkAP7ieAr8oXAW6CQdB6cAAABOAAAAEwAAAQEAAAEAAAAAAAABAAAAAQACAAAAFgAA 155 | AE8cFgKpkWwO69KKBv3NfwH+x38A/8qAAP/NgAD/0oQA/9mMAP/slwD//KwA///DAv//3Af///MV///6 156 | Jv7/9CP//9EN//2WAv/qbAH/xlMA/sNSAP7RbgX9oW4X6TAjCqMAAABPAAABEgAEAQEAAwIAAAAAAAAA 157 | AA4AAABcIhQAroVaAevSigb+yn4A/sZ+AP/NgQD/0IIA/9WFAP/fjgD/7ZkA/vuqAP//xQD//+AC///z 158 | Av//9gb//+wO/v/MCf/7lgD/6mYA/85KAP+0PwD/qzwA/rlEAP7Vagv+nGAN5ykZAKwAAABQAAAECwAB 159 | DgAAAAsAAAACHwwKAJ+IYxTn2pga/MaEDf7GhAz/yoUM/8+GDP/WjAz/35QN/+6hEP77sRT//8sj///l 160 | PP//+Er///05///xJP//0x3++6kR//CECf/Yagj+vlQI/7FICP+uRAj+rEcH/7RMBf/Nexb7k3Yo4xEQ 161 | B5gAAAIfAAENAAAAAAAAAAMbDgsAkIl6Q+L04Kb88tqs//LXmf/v1ZP/79aX//TanP/33qH//eep/v/w 162 | r///+br///7J////yv///KX//++B///edv/+z2z/98Zn//C+Z//rt2b/6LRl/+u0ZP/qsl7/6K5c/+69 163 | cfmFc0ThCgoEkwAAABsAAgEAAAAAAQAAAwYAAABCHBkRr5WJauv45MT8/OfJ//fmwP/36b//++zI//7y 164 | 0f//+Nj///3d///+4v///uL///7b///1sP//4ov//diE//nRfv/xynr/6sZ6/+fDe//mwnz/4r97/+XA 165 | e//nxYb8jnlX5hoWELAAAABGAAEABgABAAAAAAAAAAABAAAAAQsAAABLGxYJp5aDU+f23rT8/+m+//3p 166 | tv/+7Lr///PG///6z////dP+//7X///+1v//+8f//eeR//nRdP/1ynf/7cVz/+jAcP/lvnD/5L1w/+a9 167 | cf/nvnP/4710+4x2S+QXEg2oAAAATAAAAQoAAAAAAAAAAAAAAAAAAAABAAAAAgAAAQ0AAABKGBMIrJaG 168 | WeX147X6/+3G///vw/7/9cn///vS///81f///dT///3T/v/zvv/414D/8shw/+zFeP/ownX/5sB0/+XA 169 | dP/nwHP/5r9z/+K+dfuLeEzlFRILqgAAAEkAAAAMAgAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAA 170 | AA8AAABMHRkMrZeFWub46Lr7//TQ/v/40P///dX+/vzX///70///983//eu1//TPfP/vxXL/6MJ2/+bA 171 | dP/lv3L/5L1x/+a+cf/iv3j8iHZK5hsYDqwAAABNAAAADQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 172 | AAAAAAAAAAAEAAAAAQ0AAABMHRQIqJeHWeb16b77//vW/v3+1//9+9T//vXN///yyP/65K3/78p5/+rB 173 | cf/lwHP/5L9y/+S+cP/mv3P/3rt0+4p3S+YWEwypAAAASgAAAAsBAAAAAAAAAAAAAAAAAAAAAAAAAAAA 174 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAwAAABMHhkLq5uSYeT388T7//7a///71f7+8sj//u7D//jh 175 | q//qxXn/579x/+XAdP/lv3L/475y/9+8dPuId03lFhMMqwAAAEoAAAAMAwAAAAEAAAAAAAAAAAAAAAAA 176 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAA0AAABMHRwNrJ2YZ+b5+Mj7/frS//7y 177 | yf/97cP/9eGt/+jEe//mvnD/5cB2/+W/c//iv3n8iHdM5hoXDqsAAABMAQAACwAAAAAAAAAAAAAAAAAA 178 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAABLHRwMqJ2b 179 | aOb28cD7//PM/v3tx//547P+6cZ9/+O8bP/mwHf/3r13+4t4S+YXFA2pAAAASgEAAAsEAAAAAAAAAAAA 180 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA 181 | AAwAAABNICERrJ+caeX57b/8/+7N//3ou//xzoP/5r9s/+O/ePyNek/lGBYNqgAAAEwAAAAOAAAAAAAA 182 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 183 | AAAAAAAAAAAAAQAAAA4AAABNHhwOq6Odauj69MX8+Oe///bRif/yy3v8lYFU5hkWDaoAAABOAQAADQIA 184 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 185 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABLIB4Op6Wiceb47cD59t2b+pmCTecaFw+nAAAASgQA 186 | AA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 187 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAQ8AAABNIiMVroyPY+GJhlviHxsPrgAA 188 | AEsAAQAOAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 189 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAwAAABLDhEFlQ0P 190 | BpUAAABLAQIADAEBAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 191 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 192 | AAgAAAAeAAAAHAAAAAYAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 193 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 194 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 195 | AAAAAAAAAAAAAAAAAAAAAAAA///////4H///8A///+AH///AA///gAH//wAA//4AAH/8AAA/+AAAH/AA 196 | AA/gAAAHgAAAA4AAAAGAAAABgAAAAQAAAAEAAAABAAAAAwAAAAGAAAAH4AAAF/AAAB/wAAA//AAA//4A 197 | AP/+AAH//4AD///AA///wA////g///////8= 198 | 199 | 200 | -------------------------------------------------------------------------------- /Mappy/Mappy.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {A36FD888-9ACD-470B-9697-C2BC1C9266F7} 8 | WinExe 9 | Properties 10 | Mappy 11 | Mappy 12 | v4.6.2 13 | 512 14 | true 15 | false 16 | 17 | publish\ 18 | true 19 | Disk 20 | false 21 | Foreground 22 | 7 23 | Days 24 | false 25 | false 26 | true 27 | 0 28 | 1.0.0.%2a 29 | false 30 | true 31 | 32 | 33 | x64 34 | true 35 | full 36 | false 37 | bin\Debug\ 38 | DEBUG;TRACE 39 | prompt 40 | 4 41 | 42 | 43 | AnyCPU 44 | pdbonly 45 | true 46 | bin\Release\ 47 | TRACE 48 | prompt 49 | 4 50 | 51 | 52 | favicon.ico 53 | 54 | 55 | Mappy.Program 56 | 57 | 58 | false 59 | 60 | 61 | true 62 | bin\x64\Debug\ 63 | DEBUG;TRACE 64 | full 65 | x64 66 | prompt 67 | MinimumRecommendedRules.ruleset 68 | true 69 | 70 | 71 | bin\x64\Release\ 72 | TRACE 73 | true 74 | pdbonly 75 | x64 76 | prompt 77 | MinimumRecommendedRules.ruleset 78 | true 79 | 80 | 81 | 82 | ..\packages\Flurl.2.8.0\lib\net40\Flurl.dll 83 | 84 | 85 | ..\packages\Flurl.Http.2.3.2\lib\net46\Flurl.Http.dll 86 | 87 | 88 | ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll 89 | 90 | 91 | ..\packages\NLog.4.5.6\lib\net45\NLog.dll 92 | 93 | 94 | ..\packages\Sharlayan.5.0.5\lib\net462\Sharlayan.dll 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | ..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | Form 119 | 120 | 121 | App.cs 122 | 123 | 124 | 125 | 126 | 127 | 128 | Form 129 | 130 | 131 | MapViewer.cs 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | Form 143 | 144 | 145 | Viewer.cs 146 | 147 | 148 | 149 | 150 | 151 | App.cs 152 | 153 | 154 | MapViewer.cs 155 | 156 | 157 | ResXFileCodeGenerator 158 | Resources.Designer.cs 159 | Designer 160 | 161 | 162 | True 163 | Resources.resx 164 | True 165 | 166 | 167 | Viewer.cs 168 | 169 | 170 | 171 | Designer 172 | 173 | 174 | 175 | PublicSettingsSingleFileGenerator 176 | Settings.Designer.cs 177 | Designer 178 | 179 | 180 | True 181 | Settings.settings 182 | True 183 | 184 | 185 | 186 | 187 | Designer 188 | 189 | 190 | 191 | 192 | Always 193 | 194 | 195 | Always 196 | 197 | 198 | Always 199 | 200 | 201 | 202 | 203 | 204 | Always 205 | 206 | 207 | Always 208 | 209 | 210 | Always 211 | 212 | 213 | Always 214 | 215 | 216 | Always 217 | 218 | 219 | Always 220 | 221 | 222 | 223 | 224 | 225 | False 226 | Microsoft .NET Framework 4.5.2 %28x86 and x64%29 227 | true 228 | 229 | 230 | False 231 | .NET Framework 3.5 SP1 232 | false 233 | 234 | 235 | 236 | 237 | 238 | 239 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | -------------------------------------------------------------------------------- /Mappy/NLog.config: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 12 | 13 | 14 | 18 | 19 | 20 | 25 | 26 | 31 | 32 | 33 | 34 | 35 | 36 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Mappy/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace Mappy 5 | { 6 | static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | static void Main() 13 | { 14 | Application.EnableVisualStyles(); 15 | Application.SetCompatibleTextRenderingDefault(false); 16 | Application.Run(new App()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Mappy/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MAPPY")] 9 | [assembly: AssemblyDescription("MAPPY")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("XIVAPI.COM")] 12 | [assembly: AssemblyProduct("MAPPY")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("a36fd888-9acd-470b-9697-c2bc1c9266f7")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Mappy/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Mappy.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Mappy.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Drawing.Bitmap. 65 | /// 66 | internal static System.Drawing.Bitmap xivapi { 67 | get { 68 | object obj = ResourceManager.GetObject("xivapi", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Mappy/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\xivapi.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | -------------------------------------------------------------------------------- /Mappy/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Mappy.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.8.0.0")] 16 | public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | 26 | [global::System.Configuration.UserScopedSettingAttribute()] 27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 29 | public bool AlwaysOnTop { 30 | get { 31 | return ((bool)(this["AlwaysOnTop"])); 32 | } 33 | set { 34 | this["AlwaysOnTop"] = value; 35 | } 36 | } 37 | 38 | [global::System.Configuration.UserScopedSettingAttribute()] 39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 40 | [global::System.Configuration.DefaultSettingValueAttribute("10")] 41 | public int MinimumSubmitQuantity { 42 | get { 43 | return ((int)(this["MinimumSubmitQuantity"])); 44 | } 45 | set { 46 | this["MinimumSubmitQuantity"] = value; 47 | } 48 | } 49 | 50 | [global::System.Configuration.UserScopedSettingAttribute()] 51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 52 | [global::System.Configuration.DefaultSettingValueAttribute("hh:mm:ss tt")] 53 | public string TimeFormat { 54 | get { 55 | return ((string)(this["TimeFormat"])); 56 | } 57 | set { 58 | this["TimeFormat"] = value; 59 | } 60 | } 61 | 62 | [global::System.Configuration.UserScopedSettingAttribute()] 63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 64 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 65 | public bool MapBounds { 66 | get { 67 | return ((bool)(this["MapBounds"])); 68 | } 69 | set { 70 | this["MapBounds"] = value; 71 | } 72 | } 73 | 74 | [global::System.Configuration.UserScopedSettingAttribute()] 75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 76 | [global::System.Configuration.DefaultSettingValueAttribute("200")] 77 | public int MapPlayerTimerSpeed { 78 | get { 79 | return ((int)(this["MapPlayerTimerSpeed"])); 80 | } 81 | set { 82 | this["MapPlayerTimerSpeed"] = value; 83 | } 84 | } 85 | 86 | [global::System.Configuration.UserScopedSettingAttribute()] 87 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 88 | [global::System.Configuration.DefaultSettingValueAttribute("1000")] 89 | public int ScanTimerSpeed { 90 | get { 91 | return ((int)(this["ScanTimerSpeed"])); 92 | } 93 | set { 94 | this["ScanTimerSpeed"] = value; 95 | } 96 | } 97 | 98 | [global::System.Configuration.UserScopedSettingAttribute()] 99 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 100 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 101 | public bool IgnoreNoneEnglish { 102 | get { 103 | return ((bool)(this["IgnoreNoneEnglish"])); 104 | } 105 | set { 106 | this["IgnoreNoneEnglish"] = value; 107 | } 108 | } 109 | 110 | [global::System.Configuration.UserScopedSettingAttribute()] 111 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 112 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 113 | public bool ExtendLogMessages { 114 | get { 115 | return ((bool)(this["ExtendLogMessages"])); 116 | } 117 | set { 118 | this["ExtendLogMessages"] = value; 119 | } 120 | } 121 | 122 | [global::System.Configuration.UserScopedSettingAttribute()] 123 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 124 | [global::System.Configuration.DefaultSettingValueAttribute("")] 125 | public string ApiKey { 126 | get { 127 | return ((string)(this["ApiKey"])); 128 | } 129 | set { 130 | this["ApiKey"] = value; 131 | } 132 | } 133 | 134 | [global::System.Configuration.UserScopedSettingAttribute()] 135 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 136 | [global::System.Configuration.DefaultSettingValueAttribute("https://xivapi.com")] 137 | public string ApiUrl { 138 | get { 139 | return ((string)(this["ApiUrl"])); 140 | } 141 | set { 142 | this["ApiUrl"] = value; 143 | } 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /Mappy/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | False 7 | 8 | 9 | 10 10 | 11 | 12 | hh:mm:ss tt 13 | 14 | 15 | True 16 | 17 | 18 | 200 19 | 20 | 21 | 1000 22 | 23 | 24 | False 25 | 26 | 27 | False 28 | 29 | 30 | 31 | 32 | 33 | https://xivapi.com 34 | 35 | 36 | -------------------------------------------------------------------------------- /Mappy/Resources/xivapi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/Mappy/Resources/xivapi.png -------------------------------------------------------------------------------- /Mappy/Settings.cs: -------------------------------------------------------------------------------- 1 | namespace Mappy.Properties { 2 | 3 | 4 | // This class allows you to handle specific events on the settings class: 5 | // The SettingChanging event is raised before a setting's value is changed. 6 | // The PropertyChanged event is raised after a setting's value is changed. 7 | // The SettingsLoaded event is raised after the setting values are loaded. 8 | // The SettingsSaving event is raised before the setting values are saved. 9 | public sealed partial class Settings { 10 | 11 | public Settings() { 12 | // // To add event handlers for saving and changing settings, uncomment the lines below: 13 | // 14 | // this.SettingChanging += this.SettingChangingEventHandler; 15 | // 16 | // this.SettingsSaving += this.SettingsSavingEventHandler; 17 | // 18 | } 19 | 20 | private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) { 21 | // Add code to handle the SettingChangingEvent event here. 22 | } 23 | 24 | private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) { 25 | // Add code to handle the SettingsSaving event here. 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Mappy/Tracking/Saver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using Newtonsoft.Json; 5 | using Sharlayan.Core; 6 | using Mappy.Entities; 7 | using Mappy.Helpers; 8 | 9 | namespace Mappy.Tracking 10 | { 11 | public class Saver 12 | { 13 | public List savedEnemies = new List(); 14 | public List savedNpcs = new List(); 15 | 16 | /// 17 | /// Add an enemy to save list 18 | /// 19 | /// 20 | public void SaveEnemy(ActorItem entity) 21 | { 22 | try 23 | { 24 | // create new monster 25 | Entity monster = new Entity("BNPC", entity); 26 | savedEnemies.Add(monster); 27 | 28 | // Have we hit out minimum? 29 | if (savedEnemies.Count == Properties.Settings.Default.MinimumSubmitQuantity) 30 | { 31 | SubmitEnemyData(); 32 | Logger.Add("> SAVE: Enemies"); 33 | } 34 | } 35 | catch (Exception ex) 36 | { 37 | Logger.Exception(ex, "Saver -> SaveEnemy"); 38 | } 39 | 40 | } 41 | 42 | /// 43 | /// Submit Enemy data to the API 44 | /// 45 | public void SubmitEnemyData() 46 | { 47 | // submit the tracked data 48 | List savedEnemiesList = new List(savedEnemies); 49 | savedEnemies.Clear(); 50 | 51 | API.SubmitData("BNPC", savedEnemiesList); 52 | File.AppendAllText(AppHelper.getApplicationPath() + "/logs/enemies.json", JsonConvert.SerializeObject(savedEnemiesList) + Environment.NewLine); 53 | } 54 | 55 | /// 56 | /// Add an npc to save list 57 | /// 58 | /// 59 | public void SaveNpc(ActorItem entity) 60 | { 61 | try 62 | { 63 | // create new npc 64 | Entity npc = new Entity("ENPC", entity); 65 | savedNpcs.Add(npc); 66 | 67 | // Have we hit out minimum? 68 | if (savedNpcs.Count == Properties.Settings.Default.MinimumSubmitQuantity) 69 | { 70 | SubmitNpcData(); 71 | Logger.Add("> Save: NPCs"); 72 | } 73 | } 74 | catch (Exception ex) 75 | { 76 | Logger.Exception(ex, "Saver -> SaveEnemy"); 77 | } 78 | } 79 | 80 | /// 81 | /// Submit NPC data to the API 82 | /// 83 | public void SubmitNpcData() 84 | { 85 | // submit the tracked data 86 | List savedNpcsList = new List(savedNpcs); 87 | savedNpcs.Clear(); 88 | 89 | API.SubmitData("ENPC", savedNpcsList); 90 | File.AppendAllText(AppHelper.getApplicationPath() + "/logs/npcs.json", JsonConvert.SerializeObject(savedNpcsList) + Environment.NewLine); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Mappy/Tracking/Tracking.cs: -------------------------------------------------------------------------------- 1 | using Sharlayan.Core; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text.RegularExpressions; 6 | using Mappy.Helpers; 7 | 8 | namespace Mappy.Tracking 9 | { 10 | public class Tracking 11 | { 12 | protected Saver Saver = new Saver(); 13 | protected List list = new List(); 14 | protected bool axisRestricted = false; 15 | protected ActorItem Player; 16 | 17 | /// 18 | /// Nicely log a new entity 19 | /// 20 | /// 21 | /// 22 | public void LogEntity(string type, ActorItem entity) 23 | { 24 | var entityType = type.PadRight(15, ' '); 25 | var entityLevel = entity.Level.ToString().PadRight(4, ' '); 26 | var entityName = entity.Name.PadRight(30, ' '); 27 | var entityId = entity.NPCID2.ToString().PadRight(15, ' '); 28 | var entityString = $"{entityType} id: {entityId} (TypeID: {entity.TypeID}) lv.{entityLevel} {entityName}"; 29 | 30 | if (Properties.Settings.Default.ExtendLogMessages) { 31 | entityString += $"ModelID: {entity.ModelID} - NPCID1: {entity.NPCID1} - Distance: {entity.Distance} - Pos: {entity.Coordinate.X},{entity.Coordinate.Y}"; 32 | } 33 | 34 | Logger.Add(entityString); 35 | } 36 | 37 | /// 38 | /// State if this entity should be ignored or not 39 | /// 40 | /// 41 | /// 42 | public bool IsIgnored(string type, ActorItem entity) 43 | { 44 | // skip if missing data or unknown 45 | if (entity.Type.ToString().ToLower() == "unknown" 46 | || entity.Type.ToString().ToLower() == "minion" 47 | || entity.NPCID2 == 0 48 | || entity.MapID == 0 49 | || entity.Name == String.Empty) 50 | { 51 | return true; 52 | } 53 | 54 | // if enabled, non English entities will be ignored. 55 | // off by default 56 | if (Properties.Settings.Default.IgnoreNoneEnglish) { 57 | Regex rgx = new Regex("[^a-zA-Z0-9 -]"); 58 | string name = rgx.Replace(entity.Name.ToString(), ""); 59 | 60 | // name too short or too long 61 | if (entity.Name.ToString().Length < 2 || entity.Name.ToString().Length > 64) { 62 | return true; 63 | } 64 | } 65 | 66 | // has a stupid big id (100 million) 67 | if (entity.NPCID2 > 100000000) { 68 | return true; 69 | } 70 | 71 | // egis and fairies 72 | uint[] egis = { 1881, 1404, 1403, 1402, 1398, 1399 }; 73 | if (type == "BNPC" && egis.Contains(entity.ModelID)) { 74 | return true; 75 | } 76 | 77 | // we only care about entities on the same map as the player 78 | if (entity.MapID != Player.MapID) { 79 | return true; 80 | } 81 | 82 | // ignore out of range eobjs 83 | if (entity.Type.ToString().ToLower() == "eobj" && entity.NPCID2 > 50000000) { 84 | return true; 85 | } 86 | 87 | // ignore if it starts with an x 88 | if (entity.Name[0].ToString() == "×") { 89 | return true; 90 | } 91 | 92 | // has weird symbols 93 | if (entity.Name.ToString().Contains('�')) { 94 | return true; 95 | } 96 | 97 | // restrict axis 98 | if (axisRestricted) { 99 | double AxisLimit = 6; 100 | double AxisDiff = entity.Z - Player.Z; 101 | AxisDiff = Math.Abs(AxisDiff); 102 | 103 | // don't include stuff that is past the axis threshold 104 | if (AxisDiff > AxisLimit) { 105 | return true; 106 | } 107 | } 108 | 109 | return false; 110 | } 111 | 112 | /// 113 | /// Define if trackign should be restricted via it's axis, it will be true 114 | /// when the layer count is above 1 115 | /// 116 | /// 117 | public void SetAxisRestriction(bool enabled) 118 | { 119 | axisRestricted = enabled; 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Mappy/Tracking/TrackingEnemies.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Mappy.Helpers; 3 | using Sharlayan.Core; 4 | 5 | namespace Mappy.Tracking 6 | { 7 | public class TrackingEnemies : Tracking 8 | { 9 | private static int total = 0; 10 | 11 | /// 12 | /// Submit Enemy Data 13 | /// 14 | public void SubmitData() 15 | { 16 | Saver.SubmitEnemyData(); 17 | } 18 | 19 | /// 20 | /// Scan for enemies 21 | /// 22 | public void Scan() 23 | { 24 | Player = GameMemory.GetPlayer(); 25 | 26 | List entities = GameMemory.GetMonstersAroundPlayer(); 27 | 28 | if (entities.Count == 0) 29 | { 30 | return; 31 | } 32 | 33 | // loop through monsters 34 | foreach (var entity in entities) 35 | { 36 | // check if we're ignoring this entity 37 | if (IsIgnored("BNPC", entity)) 38 | { 39 | continue; 40 | } 41 | 42 | // check we havent already tracked it 43 | if (list.IndexOf(entity.ID) == -1) 44 | { 45 | total++; 46 | 47 | // add to list 48 | list.Add(entity.ID); 49 | LogEntity("BNPC", entity); 50 | 51 | // add to map 52 | App.Instance.MapViewer.AddEnemyIcon(entity); 53 | App.Instance.labelTotalEnemies.Text = total.ToString(); 54 | 55 | // save enemy 56 | Saver.SaveEnemy(entity); 57 | } 58 | } 59 | } 60 | 61 | /// 62 | /// Get a list of entities 63 | /// 64 | /// 65 | public List GetEntities() 66 | { 67 | Player = GameMemory.GetPlayer(); 68 | 69 | List entities = GameMemory.GetMonstersAroundPlayer(); 70 | 71 | // remove junk 72 | for (var i = 0; i < entities.Count; i++) 73 | { 74 | ActorItem entity = entities[i]; 75 | 76 | // check if we're ignoring this entity 77 | if (IsIgnored("BNPC", entity)) 78 | { 79 | entities.RemoveAt(i); 80 | continue; 81 | } 82 | } 83 | 84 | return entities; 85 | } 86 | 87 | /// 88 | /// Clear all recorded map markers 89 | /// 90 | public void Clear() 91 | { 92 | list.Clear(); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Mappy/Tracking/TrackingNpcs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Mappy.Helpers; 5 | using Sharlayan.Core; 6 | 7 | namespace Mappy.Tracking 8 | { 9 | public class TrackingNpcs : Tracking 10 | { 11 | private static int total = 0; 12 | 13 | /// 14 | /// Submit NPC Data 15 | /// 16 | public void SubmitData() 17 | { 18 | Saver.SubmitNpcData(); 19 | } 20 | 21 | /// 22 | /// Scan for entities 23 | /// 24 | public void Scan() 25 | { 26 | Player = GameMemory.GetPlayer(); 27 | 28 | // get npcs 29 | List entities = GameMemory.GetNpcsAroundPlayer(); 30 | if (entities.Count == 0) 31 | { 32 | return; 33 | } 34 | 35 | // loop through npcs 36 | foreach (var entity in entities) 37 | { 38 | // check if we're ignoring this entity 39 | if (IsIgnored("ENPC", entity)) 40 | { 41 | continue; 42 | } 43 | 44 | // check we havent already tracked it 45 | if (list.IndexOf(entity.NPCID2) == -1) 46 | { 47 | total++; 48 | 49 | // add to existing list 50 | list.Add(entity.NPCID2); 51 | LogEntity("ENPC", entity); 52 | 53 | // add to map 54 | App.Instance.MapViewer.AddNpcIcon(entity); 55 | App.Instance.labelTotalNpcs.Text = total.ToString(); 56 | 57 | // save npc to file 58 | Saver.SaveNpc(entity); 59 | } 60 | } 61 | } 62 | 63 | /// 64 | /// Get a list of entities 65 | /// 66 | /// 67 | public List GetEntities() 68 | { 69 | Player = GameMemory.GetPlayer(); 70 | 71 | List entities = GameMemory.GetNpcsAroundPlayer(); 72 | 73 | // remove junk 74 | for (var i = 0; i < entities.Count; i++) 75 | { 76 | ActorItem entity = entities[i]; 77 | 78 | // check if we're ignoring this entity 79 | if (IsIgnored("ENPC", entity)) 80 | { 81 | entities.RemoveAt(i); 82 | continue; 83 | } 84 | } 85 | 86 | return entities; 87 | } 88 | 89 | /// 90 | /// Clear all recorded map markers 91 | /// 92 | public void Clear() 93 | { 94 | list.Clear(); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Mappy/Tracking/TrackingPlayer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Mappy.Helpers; 4 | using Sharlayan.Core; 5 | 6 | namespace Mappy.Tracking 7 | { 8 | public class TrackingPlayer 9 | { 10 | public uint MapId = 0; 11 | 12 | // 13 | // Checks if the player has changed map, 14 | // if it returns true, it means the player has moved 15 | // maps, otherwise false the map has not changed 16 | // 17 | public bool HasMovedMap() 18 | { 19 | ActorItem Player = GameMemory.GetPlayer(); 20 | 21 | // Check for map id 22 | if (Player.MapID > 0 && Player.MapID != MapId) 23 | { 24 | // set map 25 | MapId = Player.MapID; 26 | Logger.Add($"> MAP ID: {Player.MapID}"); 27 | 28 | // Tell app to change map 29 | return true; 30 | } 31 | 32 | return false; 33 | } 34 | 35 | public uint GetMapId() 36 | { 37 | return MapId; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Mappy/Viewer.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Mappy 2 | { 3 | partial class Viewer 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Viewer)); 32 | this.scannpcs = new System.Windows.Forms.Button(); 33 | this.output = new System.Windows.Forms.RichTextBox(); 34 | this.readtarget = new System.Windows.Forms.Button(); 35 | this.button1 = new System.Windows.Forms.Button(); 36 | this.readplayer = new System.Windows.Forms.Button(); 37 | this.SuspendLayout(); 38 | // 39 | // scannpcs 40 | // 41 | this.scannpcs.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(35)))), ((int)(((byte)(35)))), ((int)(((byte)(35))))); 42 | this.scannpcs.FlatStyle = System.Windows.Forms.FlatStyle.Popup; 43 | this.scannpcs.Location = new System.Drawing.Point(16, 15); 44 | this.scannpcs.Margin = new System.Windows.Forms.Padding(4); 45 | this.scannpcs.Name = "scannpcs"; 46 | this.scannpcs.Size = new System.Drawing.Size(109, 36); 47 | this.scannpcs.TabIndex = 0; 48 | this.scannpcs.Text = "Scan NPCs"; 49 | this.scannpcs.UseVisualStyleBackColor = false; 50 | this.scannpcs.Click += new System.EventHandler(this.Scannpcs_Click); 51 | // 52 | // output 53 | // 54 | this.output.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 55 | | System.Windows.Forms.AnchorStyles.Left) 56 | | System.Windows.Forms.AnchorStyles.Right))); 57 | this.output.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); 58 | this.output.BorderStyle = System.Windows.Forms.BorderStyle.None; 59 | this.output.Font = new System.Drawing.Font("Consolas", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 60 | this.output.ForeColor = System.Drawing.Color.Gainsboro; 61 | this.output.Location = new System.Drawing.Point(16, 58); 62 | this.output.Margin = new System.Windows.Forms.Padding(4); 63 | this.output.Name = "output"; 64 | this.output.Size = new System.Drawing.Size(687, 382); 65 | this.output.TabIndex = 1; 66 | this.output.Text = ""; 67 | // 68 | // readtarget 69 | // 70 | this.readtarget.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(35)))), ((int)(((byte)(35)))), ((int)(((byte)(35))))); 71 | this.readtarget.FlatStyle = System.Windows.Forms.FlatStyle.Popup; 72 | this.readtarget.Location = new System.Drawing.Point(261, 15); 73 | this.readtarget.Margin = new System.Windows.Forms.Padding(4); 74 | this.readtarget.Name = "readtarget"; 75 | this.readtarget.Size = new System.Drawing.Size(109, 36); 76 | this.readtarget.TabIndex = 2; 77 | this.readtarget.Text = "Read Target"; 78 | this.readtarget.UseVisualStyleBackColor = false; 79 | this.readtarget.Click += new System.EventHandler(this.Readtarget_Click); 80 | // 81 | // button1 82 | // 83 | this.button1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(35)))), ((int)(((byte)(35)))), ((int)(((byte)(35))))); 84 | this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Popup; 85 | this.button1.Location = new System.Drawing.Point(133, 15); 86 | this.button1.Margin = new System.Windows.Forms.Padding(4); 87 | this.button1.Name = "button1"; 88 | this.button1.Size = new System.Drawing.Size(120, 36); 89 | this.button1.TabIndex = 3; 90 | this.button1.Text = "Scan Enemies"; 91 | this.button1.UseVisualStyleBackColor = false; 92 | this.button1.Click += new System.EventHandler(this.Button1_Click); 93 | // 94 | // readplayer 95 | // 96 | this.readplayer.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(35)))), ((int)(((byte)(35)))), ((int)(((byte)(35))))); 97 | this.readplayer.FlatStyle = System.Windows.Forms.FlatStyle.Popup; 98 | this.readplayer.Location = new System.Drawing.Point(379, 15); 99 | this.readplayer.Margin = new System.Windows.Forms.Padding(4); 100 | this.readplayer.Name = "readplayer"; 101 | this.readplayer.Size = new System.Drawing.Size(109, 36); 102 | this.readplayer.TabIndex = 4; 103 | this.readplayer.Text = "Read Player"; 104 | this.readplayer.UseVisualStyleBackColor = false; 105 | this.readplayer.Click += new System.EventHandler(this.Readplayer_Click); 106 | // 107 | // Viewer 108 | // 109 | this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); 110 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 111 | this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); 112 | this.ClientSize = new System.Drawing.Size(719, 455); 113 | this.Controls.Add(this.readplayer); 114 | this.Controls.Add(this.button1); 115 | this.Controls.Add(this.readtarget); 116 | this.Controls.Add(this.output); 117 | this.Controls.Add(this.scannpcs); 118 | this.ForeColor = System.Drawing.Color.White; 119 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 120 | this.Margin = new System.Windows.Forms.Padding(4); 121 | this.Name = "Viewer"; 122 | this.Text = "DEBUG VIEWER - FINAL FANTASY XIV MAPPY"; 123 | this.Activated += new System.EventHandler(this.Viewer_Focus); 124 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Viewer_Closing); 125 | this.Load += new System.EventHandler(this.Viewer_Load); 126 | this.ResumeLayout(false); 127 | 128 | } 129 | 130 | #endregion 131 | 132 | private System.Windows.Forms.Button scannpcs; 133 | private System.Windows.Forms.RichTextBox output; 134 | private System.Windows.Forms.Button readtarget; 135 | private System.Windows.Forms.Button button1; 136 | private System.Windows.Forms.Button readplayer; 137 | } 138 | } -------------------------------------------------------------------------------- /Mappy/Viewer.cs: -------------------------------------------------------------------------------- 1 | using Sharlayan.Core; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Windows.Forms; 5 | using Mappy.Helpers; 6 | 7 | namespace Mappy 8 | { 9 | public partial class Viewer : Form 10 | { 11 | public Viewer() 12 | { 13 | InitializeComponent(); 14 | } 15 | 16 | private void Viewer_Load(object sender, EventArgs e) 17 | { 18 | TopMost = Properties.Settings.Default.AlwaysOnTop; 19 | } 20 | 21 | private void Viewer_Focus(object sender, EventArgs e) 22 | { 23 | TopMost = Properties.Settings.Default.AlwaysOnTop; 24 | } 25 | 26 | private void Viewer_Closing(object sender, FormClosingEventArgs e) 27 | { 28 | Hide(); 29 | e.Cancel = true; 30 | } 31 | 32 | ActorItem player; 33 | 34 | /// 35 | /// Scan for npcs 36 | /// 37 | /// 38 | /// 39 | private void Scannpcs_Click(object sender, EventArgs e) 40 | { 41 | player = GameMemory.GetPlayer(); 42 | 43 | // GameMemory.getNpcsAroundPlayer(); 44 | List entities = App.Instance.TrackingNpcs.GetEntities(); 45 | 46 | // reset output 47 | output.Text = String.Format("Found: {0}", entities.Count) + Environment.NewLine + Environment.NewLine; 48 | 49 | // spit out all entities 50 | foreach(ActorItem entity in entities) 51 | { 52 | PrintEntity(entity); 53 | } 54 | } 55 | 56 | /// 57 | /// Scan for enemies 58 | /// 59 | /// 60 | /// 61 | private void Button1_Click(object sender, EventArgs e) 62 | { 63 | player = GameMemory.GetPlayer(); 64 | 65 | // GameMemory.getNpcsAroundPlayer(); 66 | List entities = App.Instance.TrackingEnemies.GetEntities(); 67 | 68 | // reset output 69 | output.Text = String.Format("Found: {0}", entities.Count) + Environment.NewLine + Environment.NewLine; 70 | 71 | // spit out all entities 72 | foreach (ActorItem entity in entities) 73 | { 74 | PrintEntity(entity); 75 | } 76 | } 77 | 78 | /// 79 | /// Scan current target 80 | /// 81 | /// 82 | /// 83 | private void Readtarget_Click(object sender, EventArgs e) 84 | { 85 | player = GameMemory.GetPlayer(); 86 | ActorItem entity = GameMemory.GetCurrentTarget(); 87 | 88 | try 89 | { 90 | output.Text = String.Format("Outputting Target:") + Environment.NewLine + Environment.NewLine; 91 | PrintEntity(entity); 92 | } 93 | catch (Exception ex) 94 | { 95 | Logger.Exception(ex, "Viewer -> readtarget_Click"); 96 | } 97 | } 98 | 99 | /// 100 | /// Read Player 101 | /// 102 | /// 103 | /// 104 | private void Readplayer_Click(object sender, EventArgs e) 105 | { 106 | player = GameMemory.GetPlayer(); 107 | 108 | try 109 | { 110 | output.Text = String.Format("Outputting Player:") + Environment.NewLine + Environment.NewLine; 111 | PrintEntity(player); 112 | } 113 | catch (Exception ex) 114 | { 115 | Logger.Exception(ex, "Viewer -> readplayer_Click"); 116 | } 117 | } 118 | 119 | /// 120 | /// Print an Actor Entity to the output window 121 | /// 122 | /// 123 | private void PrintEntity(ActorItem entity) 124 | { 125 | output.AppendText(String.Format("Name: {0}", entity.Name) + Environment.NewLine); 126 | output.AppendText(String.Format("Level: {0}", entity.Level) + Environment.NewLine); 127 | output.AppendText(String.Format("HP: {0}/{1}", entity.HPCurrent, entity.HPMax) + Environment.NewLine); 128 | output.AppendText(String.Format("MP: {0}/{1}", entity.MPCurrent, entity.MPMax) + Environment.NewLine); 129 | 130 | output.AppendText(String.Format("Model ID: {0}", entity.ModelID) + Environment.NewLine); 131 | output.AppendText(String.Format("NPCID 1: {0}", entity.NPCID1) + Environment.NewLine); 132 | output.AppendText(String.Format("NPCID 2: {0}", entity.NPCID2) + Environment.NewLine); 133 | output.AppendText(String.Format("Owner ID: {0}", entity.OwnerID) + Environment.NewLine); 134 | output.AppendText(String.Format("Memory ID: {0}", entity.ID) + Environment.NewLine); 135 | output.AppendText(String.Format("Map ID: {0}", entity.MapID) + Environment.NewLine); 136 | output.AppendText(String.Format("Map Index: {0}", entity.MapIndex) + Environment.NewLine); 137 | output.AppendText(String.Format("Map Territory: {0}", entity.MapTerritory) + Environment.NewLine); 138 | 139 | output.AppendText(String.Format("Is Casting: {0}", entity.IsCasting ? "Yes" : "No") + Environment.NewLine); 140 | output.AppendText(String.Format("Is Claimed: {0}", entity.IsClaimed ? "Yes" : "No") + Environment.NewLine); 141 | output.AppendText(String.Format("Is Fate: {0}", entity.IsFate ? "Yes" : "No") + Environment.NewLine); 142 | output.AppendText(String.Format("Status: {0}", entity.Status) + Environment.NewLine); 143 | output.AppendText(String.Format("Type: {0}", entity.Type) + Environment.NewLine); 144 | output.AppendText(String.Format("Target Type: {0}", entity.TargetType) + Environment.NewLine); 145 | 146 | output.AppendText(String.Format("Position: X {0} / Y {1} / Z {2}", entity.X, entity.Y, entity.Z) + Environment.NewLine); 147 | output.AppendText(String.Format("Distance from player: {0}", entity.GetDistanceTo(player)) + Environment.NewLine); 148 | output.AppendText("---------------------------------------------------------" + Environment.NewLine); 149 | } 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /Mappy/Viewer.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | 123 | AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA 124 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 125 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 126 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA 127 | AAABAAACAwABEQEAAB8AAAAiAQEAEQAAAAIAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 128 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 129 | AAAAAAAAAAAABAABAB4AAABlFxIGoBUTCp4AAABgAAEAFwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 130 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 131 | AAAAAAAAAAAAAAAAAAQAAQEiAAAAUyggBKyghi7nopFD4yUgC60AAABQAAAAEwAAAAIAAAAAAAAAAAAA 132 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 133 | AAAAAAAAAAAAAAABAQAAAQECAAABHwAAAFUdFwKonXYP6POyHvz2uir8qowp6CQkEKQAAABNAAAAFAAA 134 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 135 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAwABAh0AAAFaHRYApZBmB+7kmgv+5JMC/uqKAP75tRz+sKE07CYs 136 | EqgAAABRAAAAEwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 137 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAgEfAAAAVR8YAqiPZQbs1ocC/diKAP7diQD/5XMA/++D 138 | AP73xBn9oaQ16iIpDaoAAABQAAAAEwAAAAEAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 139 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQAAAgEDAAEAHQAAAFMcFgGojWUE69GIBP3TgAD+z4EA/9eB 140 | AP/aZwD/4WkA/vutAv735x78oKg26R4iEKcAAABQAAAAEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 141 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwABABwAAAFZIBgBp4piA+zQiQP9zIEA/st/ 142 | AP/PgAD/0XsA/81iAP/fZAH/+6MH/v/gA/758yb+p6o76SMmEKgAAABRAAAAFAAAAAEAAAAAAAAAAAAA 143 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAgIcAAAAUh0WAqeMZQXszIYB/cqC 144 | AP7LgAD/zX8A/9CDAP7SfgD/0GUA/99mAP/6qQn//+gU/vzzB/738CX9pJYw6SEgDKgAAABPAAAAEwAA 145 | AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQADAAAAGwAAAFMcFgKojGUE68qG 146 | Av3MgQD+yYAA/8x/AP/QfwD/1IgA/9uHAP/gbwD/7nYA//2+Ff//7yr//fYW/v/fBf74uRX8o4Ql6iIj 147 | DKcAAABRAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAwAAABsAAABXIBgAqohi 148 | BOvNiQP9yoEA/sqAAP/NgQD/zoAA/9OFAP/ckQD/7JcA/vaJAP/8oQP//94j///yMv//8yD//csJ/vmQ 149 | AP74kRD+q3ob6CghCqgAAABRAAAAFQAAAAIAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAIAAAIbAAAAUxoV 150 | BKeOZgnr0YcD/Ml/AP7KgAD/zIAA/86AAP/ShAD/24wA/+qbAP76pwD+/68B///UD///9Sz+//Yw///s 151 | G///vAn/94MD/uNkAP7ieAr8oXAW6CQdB6cAAABOAAAAEwAAAQEAAAEAAAAAAAABAAAAAQACAAAAFgAA 152 | AE8cFgKpkWwO69KKBv3NfwH+x38A/8qAAP/NgAD/0oQA/9mMAP/slwD//KwA///DAv//3Af///MV///6 153 | Jv7/9CP//9EN//2WAv/qbAH/xlMA/sNSAP7RbgX9oW4X6TAjCqMAAABPAAABEgAEAQEAAwIAAAAAAAAA 154 | AA4AAABcIhQAroVaAevSigb+yn4A/sZ+AP/NgQD/0IIA/9WFAP/fjgD/7ZkA/vuqAP//xQD//+AC///z 155 | Av//9gb//+wO/v/MCf/7lgD/6mYA/85KAP+0PwD/qzwA/rlEAP7Vagv+nGAN5ykZAKwAAABQAAAECwAB 156 | DgAAAAsAAAACHwwKAJ+IYxTn2pga/MaEDf7GhAz/yoUM/8+GDP/WjAz/35QN/+6hEP77sRT//8sj///l 157 | PP//+Er///05///xJP//0x3++6kR//CECf/Yagj+vlQI/7FICP+uRAj+rEcH/7RMBf/Nexb7k3Yo4xEQ 158 | B5gAAAIfAAENAAAAAAAAAAMbDgsAkIl6Q+L04Kb88tqs//LXmf/v1ZP/79aX//TanP/33qH//eep/v/w 159 | r///+br///7J////yv///KX//++B///edv/+z2z/98Zn//C+Z//rt2b/6LRl/+u0ZP/qsl7/6K5c/+69 160 | cfmFc0ThCgoEkwAAABsAAgEAAAAAAQAAAwYAAABCHBkRr5WJauv45MT8/OfJ//fmwP/36b//++zI//7y 161 | 0f//+Nj///3d///+4v///uL///7b///1sP//4ov//diE//nRfv/xynr/6sZ6/+fDe//mwnz/4r97/+XA 162 | e//nxYb8jnlX5hoWELAAAABGAAEABgABAAAAAAAAAAABAAAAAQsAAABLGxYJp5aDU+f23rT8/+m+//3p 163 | tv/+7Lr///PG///6z////dP+//7X///+1v//+8f//eeR//nRdP/1ynf/7cVz/+jAcP/lvnD/5L1w/+a9 164 | cf/nvnP/4710+4x2S+QXEg2oAAAATAAAAQoAAAAAAAAAAAAAAAAAAAABAAAAAgAAAQ0AAABKGBMIrJaG 165 | WeX147X6/+3G///vw/7/9cn///vS///81f///dT///3T/v/zvv/414D/8shw/+zFeP/ownX/5sB0/+XA 166 | dP/nwHP/5r9z/+K+dfuLeEzlFRILqgAAAEkAAAAMAgAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAA 167 | AA8AAABMHRkMrZeFWub46Lr7//TQ/v/40P///dX+/vzX///70///983//eu1//TPfP/vxXL/6MJ2/+bA 168 | dP/lv3L/5L1x/+a+cf/iv3j8iHZK5hsYDqwAAABNAAAADQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 169 | AAAAAAAAAAAEAAAAAQ0AAABMHRQIqJeHWeb16b77//vW/v3+1//9+9T//vXN///yyP/65K3/78p5/+rB 170 | cf/lwHP/5L9y/+S+cP/mv3P/3rt0+4p3S+YWEwypAAAASgAAAAsBAAAAAAAAAAAAAAAAAAAAAAAAAAAA 171 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAwAAABMHhkLq5uSYeT388T7//7a///71f7+8sj//u7D//jh 172 | q//qxXn/579x/+XAdP/lv3L/475y/9+8dPuId03lFhMMqwAAAEoAAAAMAwAAAAEAAAAAAAAAAAAAAAAA 173 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAA0AAABMHRwNrJ2YZ+b5+Mj7/frS//7y 174 | yf/97cP/9eGt/+jEe//mvnD/5cB2/+W/c//iv3n8iHdM5hoXDqsAAABMAQAACwAAAAAAAAAAAAAAAAAA 175 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAABLHRwMqJ2b 176 | aOb28cD7//PM/v3tx//547P+6cZ9/+O8bP/mwHf/3r13+4t4S+YXFA2pAAAASgEAAAsEAAAAAAAAAAAA 177 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA 178 | AAwAAABNICERrJ+caeX57b/8/+7N//3ou//xzoP/5r9s/+O/ePyNek/lGBYNqgAAAEwAAAAOAAAAAAAA 179 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 180 | AAAAAAAAAAAAAQAAAA4AAABNHhwOq6Odauj69MX8+Oe///bRif/yy3v8lYFU5hkWDaoAAABOAQAADQIA 181 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 182 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABLIB4Op6Wiceb47cD59t2b+pmCTecaFw+nAAAASgQA 183 | AA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 184 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAQ8AAABNIiMVroyPY+GJhlviHxsPrgAA 185 | AEsAAQAOAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 186 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAwAAABLDhEFlQ0P 187 | BpUAAABLAQIADAEBAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 188 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 189 | AAgAAAAeAAAAHAAAAAYAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 190 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 191 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 192 | AAAAAAAAAAAAAAAAAAAAAAAA///////4H///8A///+AH///AA///gAH//wAA//4AAH/8AAA/+AAAH/AA 193 | AA/gAAAHgAAAA4AAAAGAAAABgAAAAQAAAAEAAAABAAAAAwAAAAGAAAAH4AAAF/AAAB/wAAA//AAA//4A 194 | AP/+AAH//4AD///AA///wA////g///////8= 195 | 196 | 197 | -------------------------------------------------------------------------------- /Mappy/assets/aether.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/Mappy/assets/aether.png -------------------------------------------------------------------------------- /Mappy/assets/enemy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/Mappy/assets/enemy.png -------------------------------------------------------------------------------- /Mappy/assets/gathering.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/Mappy/assets/gathering.png -------------------------------------------------------------------------------- /Mappy/assets/highlight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/Mappy/assets/highlight.png -------------------------------------------------------------------------------- /Mappy/assets/map_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/Mappy/assets/map_default.png -------------------------------------------------------------------------------- /Mappy/assets/map_loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/Mappy/assets/map_loading.png -------------------------------------------------------------------------------- /Mappy/assets/npc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/Mappy/assets/npc.png -------------------------------------------------------------------------------- /Mappy/assets/object.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/Mappy/assets/object.png -------------------------------------------------------------------------------- /Mappy/assets/player.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/Mappy/assets/player.png -------------------------------------------------------------------------------- /Mappy/assets/trail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/Mappy/assets/trail.png -------------------------------------------------------------------------------- /Mappy/assets/trailmini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/Mappy/assets/trailmini.png -------------------------------------------------------------------------------- /Mappy/assets/unknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/Mappy/assets/unknown.png -------------------------------------------------------------------------------- /Mappy/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/Mappy/favicon.ico -------------------------------------------------------------------------------- /Mappy/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/Mappy/icon.ico -------------------------------------------------------------------------------- /Mappy/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DEPRECATED 2 | # FFXIV Mappy (beta) 3 | 4 | Be nice, I'm a PHP developer. 5 | 6 | ## Note: 7 | 8 | Once built and run once it will download json data from the ffxivapp repositories. There is a custom signature 9 | modification in this repo, please copy the `signatures-x64.json` to the build output folder overwriting what 10 | is currently there. For more information on the ffxiv memory module, visit: https://github.com/FFXIVAPP/sharlayan 11 | 12 | ## What is this? 13 | 14 | It is a tool that reads the FFXIV game memory and tracks enemy and npc locations (npc also includes event objects, 15 | gathering locations, spawn objects and aetherytes) 16 | 17 | If you need any help, ask Vekien on Discord: https://discord.gg/MFFVHWC 18 | 19 | ![App](app.png) 20 | -------------------------------------------------------------------------------- /app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/app.png -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xivapi/xivapi-mappy/d042dfb1b19f91b69cc606c55a5eda87591a2f3e/favicon.ico -------------------------------------------------------------------------------- /signatures-x64.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Key": "TARGET", 4 | "Value": "41bc000000e041bd01000000493bc47555488d0d", 5 | "ASMSignature": true, 6 | "PointerPath": [ 7 | 0, 8 | 144 9 | ] 10 | }, 11 | { 12 | "Key": "CHATLOG", 13 | "Value": "e8********85c0740e488b0d********33D2E8********488b0d", 14 | "ASMSignature": true, 15 | "PointerPath": [ 16 | 0, 17 | 0, 18 | 48, 19 | 908 20 | ] 21 | }, 22 | { 23 | "Key": "CHARMAP", 24 | "Value": "488b420848c1e8033da701000077248bc0488d0d", 25 | "ASMSignature": true, 26 | "PointerPath": [ 27 | 0, 28 | 0 29 | ] 30 | }, 31 | { 32 | "Key": "PARTYMAP", 33 | "Value": "488D7C242066660F1F840000000000488B17488D0D", 34 | "ASMSignature": true, 35 | "PointerPath": [ 36 | 0, 37 | 752 38 | ] 39 | }, 40 | { 41 | "Key": "PARTYCOUNT", 42 | "Value": "488D7C242066660F1F840000000000488B17488D0D", 43 | "ASMSignature": true, 44 | "PointerPath": [ 45 | 0, 46 | -26920 47 | ] 48 | }, 49 | { 50 | "Key": "MAPINFO", 51 | "Value": "", 52 | "SigScanAddress": { 53 | "value": 0 54 | }, 55 | "ASMSignature": false, 56 | "Offset": 0, 57 | "PointerPath": [ 58 | 29058524 59 | ] 60 | }, 61 | { 62 | "Key": "ZONEINFO", 63 | "Value": "", 64 | "SigScanAddress": { 65 | "value": 0 66 | }, 67 | "ASMSignature": false, 68 | "Offset": 0, 69 | "PointerPath": [ 70 | 29058536 71 | ] 72 | }, 73 | { 74 | "Key": "PLAYERINFO", 75 | "Value": "83f9ff7412448b048e8bd3488d0d", 76 | "ASMSignature": true, 77 | "PointerPath": [ 78 | 0, 79 | 0 80 | ] 81 | }, 82 | { 83 | "Key": "ENMITYMAP", 84 | "Value": "83f9ff7412448b048e8bd3488d0d", 85 | "ASMSignature": true, 86 | "PointerPath": [ 87 | 0, 88 | -4656 89 | ] 90 | }, 91 | { 92 | "Key": "ENMITY_COUNT", 93 | "Value": "83f9ff7412448b048e8bd3488d0d", 94 | "ASMSignature": true, 95 | "PointerPath": [ 96 | 0, 97 | -2352 98 | ] 99 | }, 100 | { 101 | "Key": "AGROMAP", 102 | "Value": "83f9ff7412448b048e8bd3488d0d", 103 | "ASMSignature": true, 104 | "PointerPath": [ 105 | 0, 106 | -2344 107 | ] 108 | }, 109 | { 110 | "Key": "AGRO_COUNT", 111 | "Value": "83f9ff7412448b048e8bd3488d0d", 112 | "ASMSignature": true, 113 | "PointerPath": [ 114 | 0, 115 | -40 116 | ] 117 | }, 118 | { 119 | "Key": "HOTBAR", 120 | "Value": "9C640000000000002C2C000000000000", 121 | "ASMSignature": false, 122 | "PointerPath": [ 123 | 0, 124 | 56, 125 | 48, 126 | 40, 127 | 32, 128 | 0, 129 | 0 130 | ] 131 | }, 132 | { 133 | "Key": "RECAST", 134 | "Value": "9C640000000000002C2C000000000000", 135 | "ASMSignature": false, 136 | "PointerPath": [ 137 | 0, 138 | 56, 139 | 24, 140 | 48, 141 | 32, 142 | 60 143 | ] 144 | }, 145 | { 146 | "Key": "INVENTORY", 147 | "Value": "48895C2408488974241048897C2418488B3D", 148 | "ASMSignature": true, 149 | "PointerPath": [ 150 | 0, 151 | 0 152 | ] 153 | } 154 | ] 155 | -------------------------------------------------------------------------------- /structures-x64.json: -------------------------------------------------------------------------------- 1 | { 2 | "ActorItem": { 3 | "SourceSize": 9200, 4 | "DefaultBaseOffset": 0, 5 | "DefaultStatOffset": 0, 6 | "DefaultStatusEffectOffset": 6152, 7 | "Name": 48, 8 | "ID": 116, 9 | "NPCID1": 120, 10 | "NPCID2": 128, 11 | "OwnerID": 132, 12 | "Type": 140, 13 | "GatheringStatus": 145, 14 | "Distance": 146, 15 | "TargetFlags": 148, 16 | "GatheringInvisible": 148, 17 | "X": 160, 18 | "Z": 164, 19 | "Y": 168, 20 | "Heading": 176, 21 | "EventObjectType": 190, 22 | "HitBoxRadius": 192, 23 | "Fate": 228, 24 | "IsGM": 396, 25 | "ClaimedByID": 440, 26 | "TargetType": 464, 27 | "EntityCount": 474, 28 | "TargetID": 5816, 29 | "ModelID": 5928, 30 | "ActionStatus": 5946, 31 | "HPCurrent": 5968, 32 | "HPMax": 5972, 33 | "MPCurrent": 5976, 34 | "MPMax": 5980, 35 | "TPCurrent": 5984, 36 | "GPCurrent": 5986, 37 | "GPMax": 5988, 38 | "CPCurrent": 5990, 39 | "CPMax": 5992, 40 | "Title": 5998, 41 | "Job": 6024, 42 | "Level": 6026, 43 | "Icon": 6028, 44 | "Status": 6034, 45 | "GrandCompany": 6041, 46 | "GrandCompanyRank": 6041, 47 | "DifficultyRank": 6045, 48 | "CombatFlags": 6068, 49 | "AgroFlags": 6070, 50 | "IsCasting1": 6896, 51 | "IsCasting2": 6897, 52 | "CastingID": 6900, 53 | "CastingTargetID": 6912, 54 | "CastingProgress": 6948, 55 | "CastingTime": 6952 56 | }, 57 | "ChatLogPointers": { 58 | "OffsetArrayStart": 52, 59 | "OffsetArrayPos": 60, 60 | "OffsetArrayEnd": 68, 61 | "LogStart": 76, 62 | "LogNext": 84, 63 | "LogEnd": 92 64 | }, 65 | "CurrentPlayer": { 66 | "SourceSize": 620, 67 | "JobID": 102, 68 | "PGL": 106, 69 | "GLD": 108, 70 | "MRD": 110, 71 | "ARC": 112, 72 | "LNC": 114, 73 | "THM": 116, 74 | "CNJ": 118, 75 | "CPT": 120, 76 | "BSM": 122, 77 | "ARM": 124, 78 | "GSM": 126, 79 | "LTW": 128, 80 | "WVR": 130, 81 | "ALC": 132, 82 | "CUL": 134, 83 | "MIN": 136, 84 | "BTN": 138, 85 | "FSH": 140, 86 | "ACN": 142, 87 | "ROG": 144, 88 | "MCH": 146, 89 | "DRK": 148, 90 | "AST": 150, 91 | "SAM": 152, 92 | "RDM": 154, 93 | "PGL_CurrentEXP": 160, 94 | "GLD_CurrentEXP": 164, 95 | "MRD_CurrentEXP": 168, 96 | "ARC_CurrentEXP": 172, 97 | "LNC_CurrentEXP": 176, 98 | "THM_CurrentEXP": 180, 99 | "CNJ_CurrentEXP": 184, 100 | "CPT_CurrentEXP": 188, 101 | "BSM_CurrentEXP": 192, 102 | "ARM_CurrentEXP": 196, 103 | "GSM_CurrentEXP": 200, 104 | "LTW_CurrentEXP": 204, 105 | "WVR_CurrentEXP": 208, 106 | "ALC_CurrentEXP": 212, 107 | "CUL_CurrentEXP": 216, 108 | "MIN_CurrentEXP": 220, 109 | "BTN_CurrentEXP": 224, 110 | "FSH_CurrentEXP": 228, 111 | "ACN_CurrentEXP": 232, 112 | "ROG_CurrentEXP": 236, 113 | "MCH_CurrentEXP": 240, 114 | "DRK_CurrentEXP": 244, 115 | "AST_CurrentEXP": 248, 116 | "SAM_CurrentEXP": 252, 117 | "RDM_CurrentEXP": 256, 118 | "BaseStrength": 296, 119 | "BaseDexterity": 300, 120 | "BaseVitality": 304, 121 | "BaseIntelligence": 308, 122 | "BaseMind": 312, 123 | "BasePiety": 316, 124 | "Strength": 324, 125 | "Dexterity": 328, 126 | "Vitality": 332, 127 | "Intelligence": 336, 128 | "Mind": 340, 129 | "Piety": 344, 130 | "HPMax": 348, 131 | "MPMax": 352, 132 | "TPMax": 356, 133 | "GPMax": 360, 134 | "CPMax": 364, 135 | "Tenacity": 396, 136 | "AttackPower": 400, 137 | "Defense": 404, 138 | "DirectHit": 408, 139 | "MagicDefense": 416, 140 | "CriticalHitRate": 428, 141 | "AttackMagicPotency": 452, 142 | "HealingMagicPotency": 456, 143 | "Determination": 496, 144 | "SkillSpeed": 500, 145 | "SpellSpeed": 504, 146 | "FireResistance": 0, 147 | "IceResistance": 0, 148 | "WindResistance": 0, 149 | "EarthResistance": 0, 150 | "LightningResistance": 0, 151 | "WaterResistance": 0, 152 | "SlashingResistance": 0, 153 | "PiercingResistance": 0, 154 | "BluntResistance": 0, 155 | "Craftmanship": 600, 156 | "Control": 604, 157 | "Gathering": 608, 158 | "Perception": 612 159 | }, 160 | "EnmityItem": { 161 | "SourceSize": 72, 162 | "Name": 0, 163 | "ID": 64, 164 | "Enmity": 68 165 | }, 166 | "HotBarItem": { 167 | "ContainerSize": 3456, 168 | "ItemSize": 216, 169 | "Name": 0, 170 | "KeyBinds": 103, 171 | "ID": 150 172 | }, 173 | "InventoryContainer": { 174 | "Amount": 8 175 | }, 176 | "InventoryItem": { 177 | "Slot": 4, 178 | "ID": 8, 179 | "Amount": 12, 180 | "SB": 16, 181 | "Durability": 18, 182 | "IsHQ": 20, 183 | "GlamourID": 48 184 | }, 185 | "PartyMember": { 186 | "SourceSize": 912, 187 | "DefaultStatusEffectOffset": 152, 188 | "X": 0, 189 | "Y": 4, 190 | "Z": 8, 191 | "ID": 24, 192 | "HPCurrent": 36, 193 | "HPMax": 40, 194 | "MPCurrent": 44, 195 | "MPMax": 46, 196 | "TPCurrent": 48, 197 | "Name": 52, 198 | "Job": 117, 199 | "Level": 118 200 | }, 201 | "RecastItem": { 202 | "ContainerSize": 640, 203 | "ItemSize": 44, 204 | "Category": 0, 205 | "Type": 8, 206 | "ID": 12, 207 | "Icon": 16, 208 | "CoolDownPercent": 20, 209 | "ActionProc": 21, 210 | "IsAvailable": 24, 211 | "RemainingCost": 28, 212 | "Amount": 32, 213 | "InRange": 36 214 | }, 215 | "StatusItem": { 216 | "SourceSize": 12, 217 | "StatusID": 0, 218 | "Stacks": 2, 219 | "Duration": 4, 220 | "CasterID": 8 221 | }, 222 | "TargetInfo": { 223 | "Size": 9200, 224 | "SourceSize": 200, 225 | "Current": 40, 226 | "MouseOver": 58, 227 | "Previous": 160, 228 | "Focus": 136, 229 | "CurrentID": 192 230 | } 231 | } --------------------------------------------------------------------------------