├── Mapcache Editor.sln ├── Mapcache Editor ├── App.xaml ├── App.xaml.cs ├── ApplicationConfiguration │ ├── MapcacheConfiguration.cs │ └── PathRequest.cs ├── Core │ ├── Commands │ │ ├── AddMapCommand.cs │ │ ├── CommandsHolder.cs │ │ ├── DeleteMapCommand.cs │ │ ├── IMapcacheCommand.cs │ │ └── MapcacheGroupCommand.cs │ ├── Extensions.cs │ ├── MapInfo.cs │ ├── Mapcache.cs │ ├── MapcacheDialog.xaml │ └── MapcacheDialog.xaml.cs ├── Files │ ├── ActImaging.dll │ ├── Encryption.dll │ ├── ErrorManager.dll │ ├── GRF.dll │ ├── Gif.Components.dll │ ├── GrfToWpfBridge.dll │ ├── TokeiLibrary.dll │ ├── Utilities.dll │ └── zlib.net.dll ├── Main.cs ├── Mapcache Editor.csproj ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Resources │ ├── add.png │ ├── app.ico │ ├── arrowdown.png │ ├── cache.png │ ├── convert.png │ ├── delete.png │ ├── empty.png │ ├── help.png │ ├── newFile.png │ ├── redo.png │ ├── save.png │ ├── smallArrow.png │ └── undo.png ├── WPF │ └── Styles │ │ └── GRFEditorStyles.xaml ├── app.config ├── app.ico └── app.manifest └── README.md /Mapcache Editor.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mapcache Editor", "Mapcache Editor\Mapcache Editor.csproj", "{5DBC2907-9F05-453C-91B3-7ABD1616EDE0}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|x86 = Debug|x86 9 | Release|x86 = Release|x86 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {5DBC2907-9F05-453C-91B3-7ABD1616EDE0}.Debug|x86.ActiveCfg = Debug|x86 13 | {5DBC2907-9F05-453C-91B3-7ABD1616EDE0}.Debug|x86.Build.0 = Debug|x86 14 | {5DBC2907-9F05-453C-91B3-7ABD1616EDE0}.Release|x86.ActiveCfg = Release|x86 15 | {5DBC2907-9F05-453C-91B3-7ABD1616EDE0}.Release|x86.Build.0 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /Mapcache Editor/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Mapcache Editor/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using System.Reflection; 5 | using System.Windows; 6 | using ErrorManager; 7 | using GRF.Image; 8 | using GRF.IO; 9 | using GRF.System; 10 | using GRF.Threading; 11 | using GrfToWpfBridge.Application; 12 | using Mapcache_Editor.ApplicationConfiguration; 13 | using TokeiLibrary; 14 | using Utilities; 15 | 16 | namespace Mapcache_Editor { 17 | /// 18 | /// Interaction logic for App.xaml 19 | /// 20 | public partial class App : Application { 21 | public App() { 22 | Configuration.ConfigAsker = MapcacheConfiguration.ConfigAsker; 23 | Settings.TempPath = GrfPath.Combine(MapcacheConfiguration.ProgramDataPath, "~tmp\\" + MapcacheConfiguration.ProcessId); 24 | ErrorHandler.SetErrorHandler(new DefaultErrorHandler()); 25 | 26 | if (!Directory.Exists(Settings.TempPath)) { 27 | try { 28 | GrfPath.CreateDirectoryFromFile(Settings.TempPath); 29 | } 30 | catch { 31 | } 32 | } 33 | 34 | ClearTemporaryFiles(); 35 | } 36 | 37 | /// 38 | /// Clears the temporary files, this method is different than GRFE's (and it is better). 39 | /// 40 | public static void ClearTemporaryFiles() { 41 | GrfThread.Start(delegate { 42 | int errorCount = 0; 43 | 44 | // Clear root files only 45 | foreach (string file in Directory.GetFiles(GrfPath.Combine(MapcacheConfiguration.ProgramDataPath, "~tmp"), "*", SearchOption.TopDirectoryOnly)) { 46 | if (!GrfPath.Delete(file)) { 47 | errorCount++; 48 | } 49 | 50 | if (errorCount > 20) 51 | break; 52 | } 53 | 54 | // There will be no files in the temporary folder anymore 55 | foreach (var directory in Directory.GetDirectories(GrfPath.Combine(MapcacheConfiguration.ProgramDataPath, "~tmp"), "*")) { 56 | string folderName = Path.GetFileName(directory); 57 | int processId; 58 | 59 | if (Int32.TryParse(folderName, out processId)) { 60 | try { 61 | Process.GetProcessById(processId); 62 | // Do not bother if the process exists, even if it's not SDE 63 | } 64 | catch (ArgumentException) { 65 | // The process is not running 66 | try { 67 | Directory.Delete(directory, true); 68 | } 69 | catch { } 70 | } 71 | catch { 72 | // Do nothing 73 | } 74 | } 75 | } 76 | }, "GRF - TemporaryFilesManager cleanup"); 77 | } 78 | 79 | protected override void OnStartup(StartupEventArgs e) { 80 | ApplicationManager.CrashReportEnabled = true; 81 | ImageConverterManager.AddConverter(new DefaultImageConverter()); 82 | Configuration.SetImageRendering(Resources); 83 | 84 | Resources.MergedDictionaries.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/" + Assembly.GetEntryAssembly().GetName().Name.Replace(" ", "%20") + ";component/WPF/Styles/GRFEditorStyles.xaml", UriKind.RelativeOrAbsolute) }); 85 | 86 | if (!Methods.IsWinVistaOrHigher() && Methods.IsWinXPOrHigher()) { 87 | // We are on Windows XP, force the style. 88 | _installTheme(); 89 | } 90 | 91 | base.OnStartup(e); 92 | } 93 | 94 | private bool _installTheme() { 95 | try { 96 | Uri uri = new Uri("PresentationFramework.Aero;V3.0.0.0;31bf3856ad364e35;component\\themes/aero.normalcolor.xaml", UriKind.Relative); 97 | Resources.MergedDictionaries.Add(LoadComponent(uri) as ResourceDictionary); 98 | return true; 99 | } 100 | catch { 101 | return false; 102 | } 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Mapcache Editor/ApplicationConfiguration/MapcacheConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Globalization; 4 | using System.Reflection; 5 | using System.Text; 6 | using ErrorManager; 7 | using GRF.IO; 8 | using GRF.System; 9 | using TokeiLibrary; 10 | using Utilities; 11 | 12 | namespace Mapcache_Editor.ApplicationConfiguration { 13 | /// 14 | /// Program's configuration (stored in config.txt) 15 | /// 16 | public static class MapcacheConfiguration { 17 | private static ConfigAsker _configAsker; 18 | 19 | public static ConfigAsker ConfigAsker { 20 | get { return _configAsker ?? (_configAsker = new ConfigAsker(GrfPath.Combine(Configuration.ApplicationDataPath, ProgramName, "config.txt"))); } 21 | set { _configAsker = value; } 22 | } 23 | 24 | public static string AppLastPath { 25 | get { return ConfigAsker["[Mapcache - Application latest file name]", Configuration.ApplicationPath]; } 26 | set { ConfigAsker["[Mapcache - Application latest file name]"] = value; } 27 | } 28 | 29 | public static string MapCachePath { 30 | get { return ConfigAsker["[Mapcache - MapCachePath]", Configuration.ApplicationPath]; } 31 | set { ConfigAsker["[Mapcache - MapCachePath]"] = value; } 32 | } 33 | 34 | #region Program's configuration and information 35 | 36 | public static string PublicVersion { 37 | get { return "1.0.1"; } 38 | } 39 | 40 | public static string Author { 41 | get { return "Tokeiburu"; } 42 | } 43 | 44 | public static string ProgramName { 45 | get { return "Mapcache Editor"; } 46 | } 47 | 48 | public static string RealVersion { 49 | get { return Assembly.GetEntryAssembly().GetName().Version.ToString(); } 50 | } 51 | 52 | #endregion 53 | 54 | private static int _processId = 0; 55 | 56 | public static int ProcessId { 57 | get { 58 | if (_processId == 0) 59 | _processId = Process.GetCurrentProcess().Id; 60 | 61 | return _processId; 62 | } 63 | } 64 | 65 | public static string TempPath { 66 | get { return Settings.TempPath; } 67 | } 68 | 69 | public static bool AttemptingCustomDllLoad { 70 | get { return Boolean.Parse(ConfigAsker["[GRFEditor - Loading custom DLL state]", false.ToString()]); } 71 | set { ConfigAsker["[GRFEditor - Loading custom DLL state]"] = value.ToString(); } 72 | } 73 | 74 | public static int CompressionMethod { 75 | get { return Int32.Parse(ConfigAsker["[GRFEditor - Compression method index]", "0"]); } 76 | set { ConfigAsker["[GRFEditor - Compression method index]"] = value.ToString(CultureInfo.InvariantCulture); } 77 | } 78 | 79 | public static string CustomCompressionMethod { 80 | get { return ConfigAsker["[GRFEditor - Custom compression library]", ""]; } 81 | set { ConfigAsker["[GRFEditor - Custom compression library]"] = value; } 82 | } 83 | 84 | public static string ProgramDataPath { 85 | get { return GrfPath.Combine(Configuration.ApplicationDataPath, ProgramName); } 86 | } 87 | 88 | public static ErrorLevel WarningLevel { 89 | get { return (ErrorLevel) Int32.Parse(ConfigAsker["[Server database editor - Warning level]", "0"]); } 90 | set { ConfigAsker["[Server database editor - Warning level]"] = ((int) value).ToString(CultureInfo.InvariantCulture); } 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /Mapcache Editor/ApplicationConfiguration/PathRequest.cs: -------------------------------------------------------------------------------- 1 | using TokeiLibrary.Paths; 2 | using Utilities; 3 | 4 | namespace Mapcache_Editor.ApplicationConfiguration { 5 | /// 6 | /// Copied from GRF Editor 7 | /// This class is Used when requesting paths; it saves the latest automatically 8 | /// 9 | public static class PathRequest { 10 | public static Setting ExtractSetting { 11 | get { return new Setting(null, typeof (MapcacheConfiguration).GetProperty("AppLastPath")); } 12 | } 13 | 14 | public static string SaveFileMapcache(params string[] extra) { 15 | return TkPathRequest.SaveFile(new Setting(null, typeof(MapcacheConfiguration).GetProperty("MapCachePath")), extra); 16 | } 17 | 18 | public static string OpenFileMapcache(params string[] extra) { 19 | return TkPathRequest.OpenFile(new Setting(null, typeof(MapcacheConfiguration).GetProperty("MapCachePath")), extra); 20 | } 21 | 22 | public static string[] OpenFilesCde(params string[] extra) { 23 | return TkPathRequest.OpenFiles(new Setting(null, typeof (MapcacheConfiguration).GetProperty("AppLastPath")), extra); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Mapcache Editor/Core/Commands/AddMapCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using GRF.Core; 3 | 4 | namespace Mapcache_Editor.Core.Commands { 5 | public class AddMapCommand : IMapcacheCommand { 6 | private readonly string _name; 7 | private byte[] _gat; 8 | private byte[] _rsw; 9 | private MapInfo _map; 10 | private MapInfo _conflictMap; 11 | 12 | public AddMapCommand(string name, byte[] gat, byte[] rsw) { 13 | _name = name.ToLowerInvariant(); 14 | _gat = gat; 15 | _rsw = rsw; 16 | 17 | // Execute now to reduce the memory usage 18 | _setupMap(); 19 | } 20 | 21 | public AddMapCommand(string name, MapInfo map) { 22 | _name = name.ToLowerInvariant(); 23 | _map = map; 24 | _map.Added = true; 25 | } 26 | 27 | private void _setupMap() { 28 | if (_map == null) { 29 | bool hasWater = _rsw != null; 30 | int waterHeight = _rsw != null ? (int)BitConverter.ToSingle(_rsw, 166) : -1; 31 | 32 | _map = new MapInfo(_name); 33 | _map.Xs = BitConverter.ToUInt16(_gat, 6); 34 | _map.Ys = BitConverter.ToUInt16(_gat, 10); 35 | _map.Data = new byte[_map.Xs * _map.Ys]; 36 | 37 | int offset = 14; 38 | 39 | for (int i = 0; i < _map.Len; i++) { 40 | float height = BitConverter.ToSingle(_gat, offset); 41 | int cellType = BitConverter.ToInt32(_gat, offset + 16); 42 | offset += 20; 43 | 44 | if (hasWater && cellType == 0 && height > waterHeight) 45 | cellType = 3; 46 | 47 | _map.Data[i] = (byte)cellType; 48 | } 49 | 50 | _map.Data = Compression.CompressZlib(_map.Data); 51 | _map.Added = true; 52 | _gat = null; 53 | _rsw = null; 54 | } 55 | } 56 | 57 | public void Execute(Mapcache mapcache) { 58 | _setupMap(); 59 | 60 | int index = mapcache.GetMapIndex(_name); 61 | 62 | if (index > -1) { 63 | _conflictMap = mapcache.Maps[index]; 64 | mapcache.Maps[index] = _map; 65 | } 66 | else { 67 | mapcache.Maps.Add(_map); 68 | } 69 | } 70 | 71 | public void Undo(Mapcache mapcache) { 72 | if (_conflictMap == null) 73 | mapcache.Maps.Remove(_map); 74 | else 75 | mapcache.Maps[mapcache.GetMapIndex(_name)] = _conflictMap; 76 | } 77 | 78 | public string CommandDescription { 79 | get { return "Added map '" + _name + "'"; } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Mapcache Editor/Core/Commands/CommandsHolder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using Utilities.Commands; 6 | using Utilities.Extension; 7 | 8 | namespace Mapcache_Editor.Core.Commands { 9 | public class CommandsHolder : AbstractCommand { 10 | private readonly Mapcache _mapcache; 11 | 12 | public CommandsHolder(Mapcache mapcache) { 13 | _mapcache = mapcache; 14 | } 15 | 16 | protected override void _execute(IMapcacheCommand command) { 17 | command.Execute(_mapcache); 18 | } 19 | 20 | protected override void _undo(IMapcacheCommand command) { 21 | command.Undo(_mapcache); 22 | } 23 | 24 | protected override void _redo(IMapcacheCommand command) { 25 | command.Execute(_mapcache); 26 | } 27 | 28 | /// 29 | /// Begins the commands stack grouping. 30 | /// 31 | public void Begin() { 32 | _mapcache.Commands.BeginEdit(new MapcacheGroupCommand(_mapcache, false)); 33 | } 34 | 35 | /// 36 | /// Begins the commands stack grouping and apply commands as soon as they're received. 37 | /// 38 | public void BeginNoDelay() { 39 | _mapcache.Commands.BeginEdit(new MapcacheGroupCommand(_mapcache, true)); 40 | } 41 | 42 | /// 43 | /// Ends the commands stack grouping. 44 | /// 45 | public void End() { 46 | _mapcache.Commands.EndEdit(); 47 | } 48 | 49 | public void AddMap(string gatfile) { 50 | if (!gatfile.IsExtension(".gat")) 51 | throw new Exception("Unknown extension, expected a .gat file."); 52 | 53 | string rswfile = gatfile.ReplaceExtension(".rsw"); 54 | 55 | if (!File.Exists(gatfile)) 56 | throw new FileNotFoundException(String.Format("File not found: {0}.", gatfile), gatfile); 57 | 58 | if (!File.Exists(rswfile)) 59 | throw new FileNotFoundException(String.Format("File not found: {0}.", rswfile), rswfile); 60 | 61 | _mapcache.Commands.StoreAndExecute(new AddMapCommand(Path.GetFileNameWithoutExtension(gatfile), File.ReadAllBytes(gatfile), File.ReadAllBytes(rswfile))); 62 | } 63 | 64 | public void AddMapRaw(string name, MapInfo map) { 65 | _mapcache.Commands.StoreAndExecute(new AddMapCommand(name, map)); 66 | } 67 | 68 | public void AddMap(string name, byte[] gatdata, byte[] rswdata) { 69 | _mapcache.Commands.StoreAndExecute(new AddMapCommand(name, gatdata, rswdata)); 70 | } 71 | 72 | public void DeleteMap(string name) { 73 | _mapcache.Commands.StoreAndExecute(new DeleteMapCommand(name)); 74 | } 75 | 76 | public void DeleteMaps(List names) { 77 | if (names.Count == 0) 78 | return; 79 | 80 | if (names.Count == 1) { 81 | DeleteMap(names[0]); 82 | return; 83 | } 84 | 85 | Begin(); 86 | 87 | foreach (var map in names) { 88 | DeleteMap(map); 89 | } 90 | 91 | End(); 92 | } 93 | 94 | public void AddMaps(List names) { 95 | HashSet files = new HashSet(); 96 | 97 | foreach (var file in names.Where(p => p.IsExtension(".gat", ".rsw", ".gnd"))) { 98 | files.Add(file.ReplaceExtension(".gat")); 99 | } 100 | 101 | names = files.ToList(); 102 | 103 | if (names.Count == 0) 104 | return; 105 | 106 | if (names.Count == 1) { 107 | AddMap(names[0]); 108 | return; 109 | } 110 | 111 | Begin(); 112 | 113 | foreach (var map in names) { 114 | AddMap(map); 115 | } 116 | 117 | End(); 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /Mapcache Editor/Core/Commands/DeleteMapCommand.cs: -------------------------------------------------------------------------------- 1 | namespace Mapcache_Editor.Core.Commands { 2 | public class DeleteMapCommand : IMapcacheCommand { 3 | private readonly string _name; 4 | private MapInfo _conflict; 5 | private int _index; 6 | 7 | public DeleteMapCommand(string name) { 8 | _name = name; 9 | } 10 | 11 | public void Execute(Mapcache mapcache) { 12 | _index = mapcache.GetMapIndex(_name); 13 | _conflict = mapcache.Maps[_index]; 14 | mapcache.Maps.RemoveAt(_index); 15 | } 16 | 17 | public void Undo(Mapcache mapcache) { 18 | mapcache.Maps.Insert(_index, _conflict); 19 | } 20 | 21 | public string CommandDescription { 22 | get { return "Deleted map '" + _name + "'"; } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Mapcache Editor/Core/Commands/IMapcacheCommand.cs: -------------------------------------------------------------------------------- 1 | namespace Mapcache_Editor.Core.Commands { 2 | public interface IMapcacheCommand { 3 | void Execute(Mapcache mapcache); 4 | void Undo(Mapcache mapcache); 5 | string CommandDescription { get; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Mapcache Editor/Core/Commands/MapcacheGroupCommand.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Utilities.Commands; 3 | 4 | namespace Mapcache_Editor.Core.Commands { 5 | public class MapcacheGroupCommand : IGroupCommand, IMapcacheCommand { 6 | private readonly bool _executeCommandsOnStore; 7 | private readonly Mapcache _mapcache; 8 | private readonly List _commands = new List(); 9 | private bool _firstTimeExecuted; 10 | 11 | public List Commands { 12 | get { return _commands; } 13 | } 14 | 15 | public MapcacheGroupCommand(Mapcache mapcache, bool executeCommandsOnStore = false) { 16 | _mapcache = mapcache; 17 | _executeCommandsOnStore = executeCommandsOnStore; 18 | } 19 | 20 | public void Add(IMapcacheCommand command) { 21 | _commands.Add(command); 22 | } 23 | 24 | public void Processing(IMapcacheCommand command) { 25 | if (_executeCommandsOnStore) 26 | command.Execute(_mapcache); 27 | } 28 | 29 | public void AddRange(List commands) { 30 | _commands.AddRange(commands); 31 | } 32 | 33 | public void Close() { 34 | } 35 | 36 | public void Execute(Mapcache mapcache) { 37 | if (_executeCommandsOnStore) { 38 | if (_firstTimeExecuted) { 39 | _firstTimeExecuted = false; 40 | return; 41 | } 42 | } 43 | 44 | for (int index = 0; index < _commands.Count; index++) { 45 | var command = _commands[index]; 46 | try { 47 | command.Execute(mapcache); 48 | } 49 | catch (AbstractCommandException) { 50 | _commands.RemoveAt(index); 51 | index--; 52 | } 53 | } 54 | } 55 | 56 | public void Undo(Mapcache mapcache) { 57 | for (int index = _commands.Count - 1; index >= 0; index--) { 58 | _commands[index].Undo(mapcache); 59 | } 60 | } 61 | 62 | public string CommandDescription { 63 | get { 64 | if (_commands.Count == 1) { 65 | return _commands[0].CommandDescription; 66 | } 67 | 68 | const int DisplayLimit = 2; 69 | 70 | string result = string.Format("Group command ({0}) :\r\n", _commands.Count); 71 | 72 | for (int i = 0; i < DisplayLimit && i < _commands.Count; i++) { 73 | result += " " + _commands[i].CommandDescription.Replace("\r\n", "\\r\\n").Replace("\n", "\\n") + "\r\n"; 74 | } 75 | 76 | result = result.Trim(new char[] { '\r', '\n' }); 77 | 78 | if (_commands.Count > DisplayLimit) { 79 | result += "..."; 80 | } 81 | 82 | return result; 83 | } 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Mapcache Editor/Core/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using ErrorManager; 8 | using TokeiLibrary.WPF.Styles.ListView; 9 | 10 | namespace Mapcache_Editor.Core { 11 | public static class Extensions { 12 | public static void GenerateListViewTemplate(ListView list, ListViewDataTemplateHelper.GeneralColumnInfo[] columnInfos, ListViewCustomComparer sorter, IList triggers, params string[] extraCommands) { 13 | Gen1(list); 14 | ListViewDataTemplateHelper.GenerateListViewTemplateNew(list, columnInfos, sorter, triggers, extraCommands); 15 | } 16 | 17 | public static void Gen1(ListView list) { 18 | try { 19 | Style style = new Style(); 20 | style.TargetType = typeof(ListViewItem); 21 | 22 | style.Setters.Add(new Setter( 23 | FrameworkElement.HorizontalAlignmentProperty, 24 | HorizontalAlignment.Left 25 | )); 26 | style.Setters.Add(new Setter( 27 | Control.HorizontalContentAlignmentProperty, 28 | HorizontalAlignment.Stretch 29 | )); 30 | 31 | list.ItemContainerStyle = style; 32 | } 33 | catch (Exception err) { 34 | ErrorHandler.HandleException(err); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Mapcache Editor/Core/MapInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.IO; 4 | using GRF.IO; 5 | using Utilities; 6 | using Utilities.Services; 7 | 8 | namespace Mapcache_Editor.Core { 9 | public class MapInfo : INotifyPropertyChanged { 10 | public string MapName { get; set; } 11 | public int Xs { get; set; } 12 | public int Ys { get; set; } 13 | public byte[] Data { get; set; } 14 | 15 | public int Len { 16 | get { return Data.Length; } 17 | } 18 | 19 | #region INotifyPropertyChanged Members 20 | public event PropertyChangedEventHandler PropertyChanged; 21 | #endregion 22 | 23 | public bool Normal { 24 | get { return true; } 25 | } 26 | 27 | public bool Added { get; set; } 28 | 29 | public string DisplaySize { 30 | get { return Methods.FileSizeToString(Len); } 31 | } 32 | 33 | public MapInfo(string name) { 34 | if (name.Length > 11) 35 | name = name.Substring(0, 11); 36 | MapName = name; 37 | } 38 | 39 | public MapInfo(ByteReader reader) { 40 | MapName = reader.String(12, '\0'); 41 | MapName = MapName.ToLowerInvariant(); 42 | Xs = reader.UInt16(); 43 | Ys = reader.UInt16(); 44 | int len = reader.Int32(); 45 | Data = reader.Bytes(len); 46 | } 47 | 48 | public void Write(BinaryWriter writer) { 49 | byte[] mapName = EncodingService.Ansi.GetBytes(MapName); 50 | writer.Write(mapName, 0, mapName.Length); 51 | if (mapName.Length < 12) { 52 | writer.Write(new byte[12 - mapName.Length]); 53 | } 54 | writer.Write((UInt16)Xs); 55 | writer.Write((UInt16)Ys); 56 | writer.Write(Data.Length); 57 | writer.Write(Data); 58 | } 59 | 60 | public virtual void OnPropertyChanged() { 61 | PropertyChangedEventHandler handler = PropertyChanged; 62 | if (handler != null) handler(this, new PropertyChangedEventArgs("")); 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /Mapcache Editor/Core/Mapcache.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Linq; 6 | using GRF; 7 | using GRF.IO; 8 | using GRF.System; 9 | using GRF.Threading; 10 | using Mapcache_Editor.Core.Commands; 11 | using TokeiLibrary.WPF; 12 | 13 | namespace Mapcache_Editor.Core { 14 | public class Mapcache : IProgress { 15 | static Mapcache() { 16 | TemporaryFilesManager.UniquePattern(Process.GetCurrentProcess().Id + "_mapcache_{0:0000}.dat"); 17 | } 18 | 19 | public CommandsHolder Commands { get; private set; } 20 | 21 | public string LoadedPath { get; set; } 22 | private List _maps = new List(); 23 | 24 | public UInt32 FileSize { 25 | get { return (uint)(8 + Maps.Sum(p => p.Len) + Maps.Count * 20); } 26 | } 27 | 28 | public UInt16 MapCount { 29 | get { return (ushort)Maps.Count; } 30 | } 31 | 32 | public List Maps { 33 | get { return _maps; } 34 | set { _maps = value; } 35 | } 36 | 37 | public RangeObservableCollection ViewMaps { 38 | get { return new RangeObservableCollection(Maps); } 39 | } 40 | 41 | public Mapcache(MultiType data) : this(new ByteReader(data.Data)) { 42 | LoadedPath = data.Path; 43 | } 44 | 45 | public Mapcache() { 46 | Commands = new CommandsHolder(this); 47 | } 48 | 49 | private Mapcache(ByteReader reader) { 50 | Commands = new CommandsHolder(this); 51 | 52 | _load(reader); 53 | } 54 | 55 | private void _load(ByteReader reader) { 56 | reader.UInt32(); // file size 57 | reader.UInt16(); // map count 58 | reader.UInt16(); // the header structure is 8 bytes 59 | 60 | while (reader.CanRead) { 61 | Maps.Add(new MapInfo(reader)); 62 | } 63 | } 64 | 65 | public int GetMapIndex(string name) { 66 | var map = Maps.FirstOrDefault(p => p.MapName == name); 67 | 68 | if (map == null) 69 | return -1; 70 | 71 | return Maps.IndexOf(map); 72 | } 73 | 74 | public void Save() { 75 | Save(LoadedPath); 76 | } 77 | 78 | public void Save(string filename) { 79 | if (!File.Exists(filename)) { 80 | GrfPath.CreateDirectoryFromFile(filename); 81 | 82 | using (var writer = File.Create(filename)) { 83 | Save(writer); 84 | } 85 | 86 | return; 87 | } 88 | 89 | string tempFile = TemporaryFilesManager.GetTemporaryFilePath(Process.GetCurrentProcess().Id + "_mapcache_{0:0000}.dat"); 90 | 91 | using (var writer = File.Create(tempFile)) { 92 | Save(writer); 93 | } 94 | 95 | GrfPath.CreateDirectoryFromFile(filename); 96 | GrfPath.Delete(filename); 97 | File.Copy(tempFile, filename); 98 | GrfPath.Delete(tempFile); 99 | } 100 | 101 | public void Save(Stream stream) { 102 | BinaryWriter writer = new BinaryWriter(stream); 103 | writer.Write(FileSize); 104 | writer.Write(MapCount); 105 | writer.Write((UInt16)0); 106 | 107 | foreach (var map in Maps) { 108 | map.Write(writer); 109 | } 110 | } 111 | 112 | public void Load(string file) { 113 | Maps.Clear(); 114 | _load(new ByteReader(File.ReadAllBytes(file))); 115 | LoadedPath = file; 116 | Commands.ClearCommands(); 117 | } 118 | 119 | public void Reset() { 120 | Maps.Clear(); 121 | LoadedPath = null; 122 | Commands.ClearCommands(); 123 | } 124 | 125 | public float Progress { get; set; } 126 | public bool IsCancelling { get; set; } 127 | public bool IsCancelled { get; set; } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /Mapcache Editor/Core/MapcacheDialog.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /Mapcache Editor/Core/MapcacheDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Windows; 7 | using System.Windows.Input; 8 | using ErrorManager; 9 | using GRF.Core; 10 | using GRF.Threading; 11 | using GrfToWpfBridge.Application; 12 | using Mapcache_Editor.ApplicationConfiguration; 13 | using Mapcache_Editor.Core.Commands; 14 | using TokeiLibrary; 15 | using TokeiLibrary.Shortcuts; 16 | using TokeiLibrary.WPF; 17 | using TokeiLibrary.WPF.Styles; 18 | using TokeiLibrary.WPF.Styles.ListView; 19 | using Utilities; 20 | using Utilities.Extension; 21 | using Utilities.Services; 22 | using AsyncOperation = GrfToWpfBridge.Application.AsyncOperation; 23 | 24 | namespace Mapcache_Editor.Core { 25 | /// 26 | /// Interaction logic for ScriptEditDialog.xaml 27 | /// 28 | public partial class MapcacheDialog : TkWindow { 29 | private readonly Mapcache _cache; 30 | private readonly WpfRecentFiles _recentFilesManager; 31 | private readonly AsyncOperation _asyncOperation; 32 | 33 | public MapcacheDialog() 34 | : base("Mapcache", "cache.png", SizeToContent.Manual, ResizeMode.CanResize) { 35 | 36 | InitializeComponent(); 37 | 38 | ShowInTaskbar = true; 39 | WindowStartupLocation = WindowStartupLocation.CenterOwner; 40 | 41 | _cache = new Mapcache(); 42 | _cache.Commands.ModifiedStateChanged += _commands_ModifiedStateChanged; 43 | _asyncOperation = new AsyncOperation(_progressBar); 44 | 45 | Extensions.GenerateListViewTemplate(_listView, new ListViewDataTemplateHelper.GeneralColumnInfo[] { 46 | new ListViewDataTemplateHelper.GeneralColumnInfo { Header = "Name", DisplayExpression = "MapName", SearchGetAccessor = "MapName", ToolTipBinding = "MapName", TextWrapping = TextWrapping.Wrap, TextAlignment = TextAlignment.Center, FixedWidth = 140 }, 47 | new ListViewDataTemplateHelper.GeneralColumnInfo { Header = "Width", DisplayExpression = "Xs", SearchGetAccessor = "Xs", ToolTipBinding = "Xs", TextAlignment = TextAlignment.Center, FixedWidth = 80 }, 48 | new ListViewDataTemplateHelper.GeneralColumnInfo { Header = "Height", DisplayExpression = "Ys", SearchGetAccessor = "Ys", ToolTipBinding = "Ys", TextAlignment = TextAlignment.Center, FixedWidth = 80 }, 49 | new ListViewDataTemplateHelper.GeneralColumnInfo { Header = "Size", DisplayExpression = "DisplaySize", SearchGetAccessor = "Len", ToolTipBinding = "DisplaySize", TextAlignment = TextAlignment.Center, FixedWidth = 150 }, 50 | }, new DefaultListViewComparer(), new string[] { "Added", "Blue" }); 51 | 52 | _tmbUndo.SetUndo(_cache.Commands); 53 | _tmbRedo.SetRedo(_cache.Commands); 54 | _commands_ModifiedStateChanged(null, null); 55 | _listView.ItemsSource = _cache.ViewMaps; 56 | 57 | ApplicationShortcut.Link(ApplicationShortcut.Save, () => _menuItemSave_Click(null, null), this); 58 | ApplicationShortcut.Link(ApplicationShortcut.Undo, () => _cache.Commands.Undo(), this); 59 | ApplicationShortcut.Link(ApplicationShortcut.Redo, () => _cache.Commands.Redo(), this); 60 | ApplicationShortcut.Link(ApplicationShortcut.New, () => _menuItemNew_Click(null, null), this); 61 | ApplicationShortcut.Link(ApplicationShortcut.Open, () => _menuItemOpenFrom_Click(null, null), this); 62 | ApplicationShortcut.Link(ApplicationShortcut.Delete, () => _miDelete_Click(null, null), this); 63 | 64 | _recentFilesManager = new WpfRecentFiles(Configuration.ConfigAsker, 6, _menuItemRecentFiles, "Mapcache"); 65 | _recentFilesManager.FileClicked += _recentFilesManager_FileClicked; 66 | 67 | if (_recentFilesManager.Files.Count > 0 && File.Exists(_recentFilesManager.Files[0])) { 68 | _load(_recentFilesManager.Files[0]); 69 | } 70 | } 71 | 72 | private void _commands_ModifiedStateChanged(object sender, IMapcacheCommand command) { 73 | this.Dispatch(delegate { 74 | if (_cache.LoadedPath != null) { 75 | this.Title = "Mapcache - " + Methods.CutFileName(_cache.LoadedPath, 50) + (_cache.Commands.IsModified ? " *" : ""); 76 | } 77 | else { 78 | this.Title = "Mapcache - map_cache.dat *"; 79 | } 80 | 81 | _labelMapCount.Content = "Map count: " + _cache.MapCount; 82 | _labelMapAdded.Content = "Added: " + _cache.Maps.Count(p => p.Added); 83 | _labelSize.Content = "File Size: " + _cache.FileSize + " (" + Methods.FileSizeToString(_cache.FileSize) + ")"; 84 | _listView.ItemsSource = _cache.ViewMaps; 85 | }); 86 | } 87 | 88 | private void _miDelete_Click(object sender, RoutedEventArgs e) { 89 | try { 90 | if (!_validateState()) 91 | return; 92 | _cache.Commands.DeleteMaps(_listView.SelectedItems.OfType().Select(p => p.MapName).ToList()); 93 | } 94 | catch (Exception err) { 95 | ErrorHandler.HandleException(err); 96 | } 97 | } 98 | 99 | private bool _validateState() { 100 | if (_asyncOperation.IsRunning) { 101 | ErrorHandler.HandleException("An operation is currently running, wait for it to finish or cancel it.", ErrorLevel.NotSpecified); 102 | return false; 103 | } 104 | 105 | return true; 106 | } 107 | 108 | private void _menuItemSave_Click(object sender, RoutedEventArgs e) { 109 | if (!_validateState()) 110 | return; 111 | 112 | if (_cache.LoadedPath == null) { 113 | _menuItemSaveAs_Click(sender, e); 114 | return; 115 | } 116 | 117 | _cache.Save(_cache.LoadedPath); 118 | _cache.LoadedPath = _cache.LoadedPath; 119 | _cache.Commands.SaveCommandIndex(); 120 | _fakeProgress(0); 121 | } 122 | 123 | private void _menuItemSaveAs_Click(object sender, RoutedEventArgs e) { 124 | if (!_validateState()) 125 | return; 126 | 127 | try { 128 | string file = PathRequest.SaveFileMapcache("filter", "Dat Files (*.dat)|*.dat", "fileName", Path.GetFileName(_cache.LoadedPath ?? "map_cache.dat")); 129 | 130 | if (file != null) { 131 | _cache.Save(file); 132 | _cache.LoadedPath = file; 133 | _cache.Commands.SaveCommandIndex(); 134 | _fakeProgress(0); 135 | } 136 | } 137 | catch (Exception err) { 138 | ErrorHandler.HandleException(err); 139 | } 140 | } 141 | 142 | private void _fakeProgress(int mode) { 143 | if (mode == 1) { 144 | _asyncOperation.SetAndRunOperation(new GrfThread(_dull, _cache, 200), delegate { 145 | _progressBar.SetSpecialState(TkProgressBar.ProgressStatus.FileLoaded); 146 | }); 147 | } 148 | else 149 | _asyncOperation.SetAndRunOperation(new GrfThread(_dull, _cache, 200)); 150 | } 151 | 152 | private void _dull() { 153 | AProgress.Finalize(_cache); 154 | } 155 | 156 | private void _menuItemAbout_Click(object sender, RoutedEventArgs e) { 157 | WindowProvider.ShowWindow(new AboutDialog(MapcacheConfiguration.PublicVersion, MapcacheConfiguration.RealVersion, MapcacheConfiguration.Author, MapcacheConfiguration.ProgramName), this); 158 | } 159 | 160 | private void _menuItemQuit_Click(object sender, RoutedEventArgs e) { 161 | Close(); 162 | } 163 | 164 | protected override void OnClosing(CancelEventArgs e) { 165 | try { 166 | if (_cache != null && _cache.Commands.IsModified) { 167 | MessageBoxResult res = WindowProvider.ShowDialog("The map cache has been modified, do you want to save it first?", "Modified map cache", MessageBoxButton.YesNoCancel); 168 | 169 | if (res == MessageBoxResult.Yes) { 170 | _menuItemSaveAs_Click(null, null); 171 | e.Cancel = true; 172 | return; 173 | } 174 | 175 | if (res == MessageBoxResult.Cancel) { 176 | e.Cancel = true; 177 | return; 178 | } 179 | } 180 | 181 | ApplicationManager.Shutdown(); 182 | base.OnClosing(e); 183 | } 184 | catch (Exception err) { 185 | try { 186 | ErrorHandler.HandleException("The application hasn't ended properly. Please report this issue.", err); 187 | } 188 | catch { 189 | } 190 | } 191 | } 192 | 193 | private void _menuItemOpenFrom_Click(object sender, RoutedEventArgs e) { 194 | try { 195 | string file = PathRequest.OpenFileMapcache("filter", "Dat Files (*.dat)|*.dat"); 196 | 197 | if (file != null) { 198 | if (File.Exists(file)) { 199 | _load(file); 200 | _recentFilesManager.AddRecentFile(file); 201 | } 202 | } 203 | } 204 | catch (Exception err) { 205 | ErrorHandler.HandleException(err); 206 | } 207 | } 208 | 209 | private void _load(string file) { 210 | if (file.IsExtension(".dat")) { 211 | if (_validateNewContainer()) { 212 | _cache.Load(file); 213 | _commands_ModifiedStateChanged(null, null); 214 | _fakeProgress(1); 215 | } 216 | } 217 | } 218 | 219 | private bool _validateNewContainer() { 220 | try { 221 | if (!_validateState()) 222 | return false; 223 | 224 | if (_cache.Commands.IsModified) { 225 | MessageBoxResult res = WindowProvider.ShowDialog("The map cache has been modified, do you want to save it first?", "Modified map cache", MessageBoxButton.YesNoCancel); 226 | 227 | if (res == MessageBoxResult.Yes) { 228 | _menuItemSaveAs_Click(null, null); 229 | return false; 230 | } 231 | 232 | if (res == MessageBoxResult.Cancel) { 233 | return false; 234 | } 235 | } 236 | } 237 | catch { 238 | return true; 239 | } 240 | 241 | return true; 242 | } 243 | 244 | private void _recentFilesManager_FileClicked(string fileName) { 245 | try { 246 | if (File.Exists(fileName)) { 247 | _load(fileName); 248 | } 249 | else { 250 | ErrorHandler.HandleException("File not found : " + fileName, ErrorLevel.Low); 251 | _recentFilesManager.RemoveRecentFile(fileName); 252 | } 253 | } 254 | catch (Exception err) { 255 | ErrorHandler.HandleException(err); 256 | } 257 | } 258 | 259 | private void _menuItemCloseGrf_Click(object sender, RoutedEventArgs e) { 260 | try { 261 | if (_validateNewContainer()) { 262 | _cache.Reset(); 263 | _progressBar.Progress = 0; 264 | _commands_ModifiedStateChanged(null, null); 265 | } 266 | } 267 | catch (Exception err) { 268 | ErrorHandler.HandleException(err); 269 | } 270 | } 271 | 272 | private void _menuItemSelect_Click(object sender, RoutedEventArgs e) { 273 | try { 274 | if (_cache.LoadedPath == null) 275 | throw new Exception("No file has been loaded."); 276 | 277 | OpeningService.FileOrFolder(_cache.LoadedPath); 278 | } 279 | catch (Exception err) { 280 | ErrorHandler.HandleException(err); 281 | } 282 | } 283 | 284 | private void _menuItemNew_Click(object sender, RoutedEventArgs e) { 285 | _menuItemCloseGrf_Click(null, null); 286 | } 287 | 288 | private void _listView_DragEnter(object sender, DragEventArgs e) { 289 | e.Effects = DragDropEffects.Copy; 290 | } 291 | 292 | private void _listView_Drop(object sender, DragEventArgs e) { 293 | try { 294 | if (!_validateState()) 295 | return; 296 | 297 | if (e.Data.GetDataPresent(DataFormats.FileDrop, true)) { 298 | string[] files = e.Data.GetData(DataFormats.FileDrop, true) as string[]; 299 | 300 | if (files == null) 301 | return; 302 | 303 | if (files.Length == 1 && files[0].IsExtension(".dat")) { 304 | _load(files[0]); 305 | _recentFilesManager.AddRecentFile(files[0]); 306 | } 307 | else { 308 | _cache.Commands.AddMaps(files.ToList()); 309 | } 310 | } 311 | } 312 | catch (Exception err) { 313 | ErrorHandler.HandleException(err); 314 | } 315 | } 316 | 317 | private void _menuItemAdd_Click(object sender, RoutedEventArgs e) { 318 | try { 319 | string[] files = PathRequest.OpenFilesCde("filter", "Gat Files (*.gat)|*.gat"); 320 | 321 | if (files != null) { 322 | _cache.Commands.AddMaps(files.ToList()); 323 | } 324 | } 325 | catch (Exception err) { 326 | ErrorHandler.HandleException(err); 327 | } 328 | } 329 | 330 | private void _menuItemDelete_Click(object sender, RoutedEventArgs e) { 331 | _miDelete_Click(null, null); 332 | } 333 | 334 | private void _buttonUndo_Click(object sender, RoutedEventArgs e) { 335 | if (!_validateState()) 336 | return; 337 | _cache.Commands.Undo(); 338 | } 339 | 340 | private void _buttonRedo_Click(object sender, RoutedEventArgs e) { 341 | if (!_validateState()) 342 | return; 343 | _cache.Commands.Redo(); 344 | } 345 | 346 | private void Border_MouseDown(object sender, MouseButtonEventArgs e) { 347 | if (e.ChangedButton == MouseButton.Left) 348 | this.DragMove(); 349 | } 350 | 351 | private void _menuItemMerge_Click(object sender, RoutedEventArgs e) { 352 | try { 353 | if (!_validateState()) 354 | return; 355 | 356 | string file = PathRequest.OpenFileMapcache("filter", "Grf and Dat Files (*.grf, *.dat)|*.grf;*.dat"); 357 | 358 | if (file != null) { 359 | if (file.IsExtension(".grf")) { 360 | _asyncOperation.SetAndRunOperation(new GrfThread(delegate { 361 | AProgress.Init(_cache); 362 | 363 | try { 364 | _cache.Commands.Begin(); 365 | 366 | List files = new List(); 367 | int count = 0; 368 | 369 | using (GrfHolder grf = new GrfHolder(file, GrfLoadOptions.Normal)) { 370 | files.AddRange(grf.FileTable.EntriesInDirectory("data\\", SearchOption.TopDirectoryOnly).Where(entry => entry.RelativePath.IsExtension(".gat"))); 371 | 372 | foreach (var entry in files) { 373 | count++; 374 | AProgress.IsCancelling(_cache); 375 | FileEntry rswEntry = grf.FileTable.TryGet(entry.RelativePath.ReplaceExtension(".rsw")); 376 | 377 | if (rswEntry == null) 378 | continue; 379 | 380 | _cache.Progress = (float)count / files.Count * 100f; 381 | _cache.Commands.AddMap(Path.GetFileNameWithoutExtension(entry.DisplayRelativePath), entry.GetDecompressedData(), rswEntry.GetDecompressedData()); 382 | } 383 | } 384 | } 385 | catch (OperationCanceledException) { 386 | _cache.IsCancelled = true; 387 | _cache.Commands.CancelEdit(); 388 | } 389 | catch (Exception err) { 390 | _cache.Commands.CancelEdit(); 391 | ErrorHandler.HandleException(err); 392 | } 393 | finally { 394 | _cache.Commands.End(); 395 | AProgress.Finalize(_cache); 396 | } 397 | }, _cache, 200)); 398 | } 399 | else if (file.IsExtension(".dat")) { 400 | Mapcache cache = new Mapcache(file); 401 | 402 | try { 403 | _cache.Commands.Begin(); 404 | 405 | foreach (var map in cache.Maps) { 406 | _cache.Commands.AddMapRaw(map.MapName, map); 407 | } 408 | } 409 | catch { 410 | _cache.Commands.CancelEdit(); 411 | throw; 412 | } 413 | finally { 414 | _cache.Commands.End(); 415 | } 416 | } 417 | else { 418 | throw new Exception("Unreognized file format."); 419 | } 420 | } 421 | } 422 | catch (Exception err) { 423 | ErrorHandler.HandleException(err); 424 | } 425 | } 426 | } 427 | } 428 | -------------------------------------------------------------------------------- /Mapcache Editor/Files/ActImaging.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Files/ActImaging.dll -------------------------------------------------------------------------------- /Mapcache Editor/Files/Encryption.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Files/Encryption.dll -------------------------------------------------------------------------------- /Mapcache Editor/Files/ErrorManager.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Files/ErrorManager.dll -------------------------------------------------------------------------------- /Mapcache Editor/Files/GRF.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Files/GRF.dll -------------------------------------------------------------------------------- /Mapcache Editor/Files/Gif.Components.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Files/Gif.Components.dll -------------------------------------------------------------------------------- /Mapcache Editor/Files/GrfToWpfBridge.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Files/GrfToWpfBridge.dll -------------------------------------------------------------------------------- /Mapcache Editor/Files/TokeiLibrary.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Files/TokeiLibrary.dll -------------------------------------------------------------------------------- /Mapcache Editor/Files/Utilities.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Files/Utilities.dll -------------------------------------------------------------------------------- /Mapcache Editor/Files/zlib.net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Files/zlib.net.dll -------------------------------------------------------------------------------- /Mapcache Editor/Main.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using System.IO.Compression; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Windows; 8 | using Mapcache_Editor; 9 | 10 | namespace SDE { 11 | public class GRFEditorMain { 12 | private static readonly string[] _registeredAssemblies = new string[] { 13 | "ErrorManager", 14 | "ICSharpCode.AvalonEdit", 15 | "GRF", 16 | "TokeiLibrary", 17 | "PaletteRecolorer", 18 | "Be.Windows.Forms.HexBox", 19 | "zlib.net", 20 | "Utilities", 21 | "cps", 22 | "Encryption", 23 | "Gif.Components", 24 | "ColorPicker", 25 | "GrfMenuHandler64", 26 | "GrfMenuHandler32", 27 | "msvcp100", 28 | "msvcr100", 29 | "ActImaging", 30 | "Database", 31 | "Lua", 32 | "XDMessaging", 33 | "ErrorManager", 34 | "GrfToWpfBridge", 35 | "System.Threading", 36 | }; 37 | 38 | [STAThread] 39 | public static void Main(string[] args) { 40 | AppDomain.CurrentDomain.AssemblyResolve += (sender, arguments) => { 41 | AssemblyName assemblyName = new AssemblyName(arguments.Name); 42 | 43 | if (assemblyName.Name.EndsWith(".resources")) 44 | return null; 45 | 46 | string resourceName = "Mapcache_Editor.Files." + assemblyName.Name + ".dll"; 47 | 48 | using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) { 49 | if (stream != null) { 50 | byte[] assemblyData = new Byte[stream.Length]; 51 | stream.Read(assemblyData, 0, assemblyData.Length); 52 | return Assembly.Load(assemblyData); 53 | } 54 | } 55 | 56 | string compressedResourceName = "Mapcache_Editor.Files.Compressed." + new AssemblyName(arguments.Name).Name + ".dll"; 57 | 58 | using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(compressedResourceName)) { 59 | if (stream != null) { 60 | byte[] assemblyData = new Byte[stream.Length]; 61 | stream.Read(assemblyData, 0, assemblyData.Length); 62 | return Assembly.Load(Decompress(assemblyData)); 63 | } 64 | } 65 | 66 | if (_registeredAssemblies.ToList().Contains(assemblyName.Name)) { 67 | MessageBox.Show("Failed to load assembly : " + resourceName + "\r\n\r\nThe application will now shutdown.", "Assembly loader"); 68 | Process.GetCurrentProcess().Kill(); 69 | } 70 | 71 | return null; 72 | }; 73 | 74 | Directory.SetCurrentDirectory(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)); 75 | 76 | var app = new App(); 77 | app.StartupUri = new Uri("Core\\MapcacheDialog.xaml", UriKind.Relative); 78 | app.Run(); 79 | } 80 | 81 | public static byte[] Decompress(byte[] data) { 82 | using (MemoryStream memStream = new MemoryStream(data)) 83 | using (GZipStream stream = new GZipStream(memStream, CompressionMode.Decompress)) { 84 | const int size = 4096; 85 | byte[] buffer = new byte[size]; 86 | using (MemoryStream memory = new MemoryStream()) { 87 | int count; 88 | do { 89 | count = stream.Read(buffer, 0, size); 90 | if (count > 0) { 91 | memory.Write(buffer, 0, count); 92 | } 93 | } 94 | while (count > 0); 95 | return memory.ToArray(); 96 | } 97 | } 98 | } 99 | 100 | public static byte[] Compress(byte[] data) { 101 | using (MemoryStream memory = new MemoryStream()) { 102 | using (GZipStream gzip = new GZipStream(memory, CompressionMode.Compress, true)) { 103 | gzip.Write(data, 0, data.Length); 104 | } 105 | return memory.ToArray(); 106 | } 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Mapcache Editor/Mapcache Editor.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {5DBC2907-9F05-453C-91B3-7ABD1616EDE0} 9 | WinExe 10 | Properties 11 | Mapcache_Editor 12 | Mapcache Editor 13 | v3.5 14 | 512 15 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 16 | 4 17 | Client 18 | 19 | 20 | x86 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | 29 | 30 | x86 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | 38 | 39 | app.manifest 40 | 41 | 42 | SDE.GRFEditorMain 43 | 44 | 45 | app.ico 46 | 47 | 48 | 49 | ..\..\..\..\..\..\..\tktoolsuite\Librairies\ErrorManager.dll 50 | 51 | 52 | ..\..\..\..\..\..\..\tktoolsuite\Librairies\GRF.dll 53 | 54 | 55 | ..\..\..\..\..\..\..\tktoolsuite\Librairies\GrfToWpfBridge.dll 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | ..\..\..\..\..\..\..\tktoolsuite\Librairies\TokeiLibrary.dll 65 | 66 | 67 | ..\..\..\..\..\..\..\tktoolsuite\Librairies\Utilities.dll 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | MSBuild:Compile 76 | Designer 77 | 78 | 79 | MSBuild:Compile 80 | Designer 81 | 82 | 83 | App.xaml 84 | Code 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | MapcacheDialog.xaml 97 | 98 | 99 | 100 | 101 | MSBuild:Compile 102 | Designer 103 | 104 | 105 | 106 | 107 | Code 108 | 109 | 110 | True 111 | True 112 | Resources.resx 113 | 114 | 115 | True 116 | Settings.settings 117 | True 118 | 119 | 120 | ResXFileCodeGenerator 121 | Resources.Designer.cs 122 | 123 | 124 | 125 | 126 | SettingsSingleFileGenerator 127 | Settings.Designer.cs 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 179 | -------------------------------------------------------------------------------- /Mapcache Editor/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("Mapcache Editor")] 11 | [assembly: AssemblyDescription("Mapcache Editor")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("Tokei")] 14 | [assembly: AssemblyProduct("Mapcache Editor")] 15 | [assembly: AssemblyCopyright("Copyright © 2018")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | // You can specify all the values or you can default the Build and Revision Numbers 52 | // by using the '*' as shown below: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("1.0.0.0")] 55 | [assembly: AssemblyFileVersion("1.0.0.0")] 56 | -------------------------------------------------------------------------------- /Mapcache Editor/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 Mapcache_Editor.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", "4.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("Mapcache_Editor.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 | -------------------------------------------------------------------------------- /Mapcache Editor/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 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /Mapcache Editor/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 Mapcache_Editor.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] 16 | internal 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 | } 27 | -------------------------------------------------------------------------------- /Mapcache Editor/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Mapcache Editor/Resources/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Resources/add.png -------------------------------------------------------------------------------- /Mapcache Editor/Resources/app.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Resources/app.ico -------------------------------------------------------------------------------- /Mapcache Editor/Resources/arrowdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Resources/arrowdown.png -------------------------------------------------------------------------------- /Mapcache Editor/Resources/cache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Resources/cache.png -------------------------------------------------------------------------------- /Mapcache Editor/Resources/convert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Resources/convert.png -------------------------------------------------------------------------------- /Mapcache Editor/Resources/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Resources/delete.png -------------------------------------------------------------------------------- /Mapcache Editor/Resources/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Resources/empty.png -------------------------------------------------------------------------------- /Mapcache Editor/Resources/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Resources/help.png -------------------------------------------------------------------------------- /Mapcache Editor/Resources/newFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Resources/newFile.png -------------------------------------------------------------------------------- /Mapcache Editor/Resources/redo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Resources/redo.png -------------------------------------------------------------------------------- /Mapcache Editor/Resources/save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Resources/save.png -------------------------------------------------------------------------------- /Mapcache Editor/Resources/smallArrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Resources/smallArrow.png -------------------------------------------------------------------------------- /Mapcache Editor/Resources/undo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/Resources/undo.png -------------------------------------------------------------------------------- /Mapcache Editor/WPF/Styles/GRFEditorStyles.xaml: -------------------------------------------------------------------------------- 1 |  3 | 6 | 9 | 12 | 13 | 18 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 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 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 204 | 205 | 248 | 249 | 294 | 295 | 343 | 344 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | -------------------------------------------------------------------------------- /Mapcache Editor/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Mapcache Editor/app.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tokeiburu/Mapcache-Editor/df03764544f3fb0595a41da93e1466b517e04649/Mapcache Editor/app.ico -------------------------------------------------------------------------------- /Mapcache Editor/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mapcache-Editor 2 | A Mapcache Editor for rAthena. 3 | --------------------------------------------------------------------------------