├── .gitattributes ├── .gitignore ├── DebugPlatform ├── App.config ├── DebugPlatform.csproj ├── GraphList.cs ├── Last-Modified - 副本.xml ├── Last-Modified.xml ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── Settings.cs ├── KanColleCacher.sln ├── KanColleCacher ├── CacheCore.cs ├── CacherToolView.xaml ├── CacherToolView.xaml.cs ├── ConfigParser.cs ├── Extension.cs ├── FiddlerRules.cs ├── GMTHelper.cs ├── GraphList.cs ├── KanColleCacher.cs ├── KanColleCacher.csproj ├── Libraries │ ├── FiddlerCore4.dll │ ├── FiddlerCore4.xml │ ├── KanColleViewer.exe │ ├── KanColleWrapper.dll │ ├── Livet.Extensions.dll │ ├── Livet.Extensions.xml │ ├── Livet.dll │ └── Portable.dll ├── Log.cs ├── Properties │ └── AssemblyInfo.cs ├── RecentRecord.cs ├── Settings - 副本.cs ├── Settings.cs ├── ValidationRule.cs ├── ValueConverter.cs └── VersionChecker.cs ├── KanColleModifier.KCV - 副本 ├── KanColleModifier.KCV.csproj ├── Libraries │ ├── FiddlerCore4.dll │ └── KanColleViewer.exe ├── Modifier.cs ├── ModifierInitializer.cs ├── ModifierView.xaml ├── ModifierView.xaml.cs └── Properties │ └── AssemblyInfo.cs ├── LICENSE └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/df32/KanColleCacher/1298d9f7799fac94050e979fcad289163c41f2d5/.gitignore -------------------------------------------------------------------------------- /DebugPlatform/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /DebugPlatform/DebugPlatform.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D8F14FD8-B541-40B0-9D52-32FF0A7EB6B3} 8 | Exe 9 | Properties 10 | DebugPlatform 11 | DebugPlatform 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | ..\KanColleCacher\Libraries\FiddlerCore4.dll 37 | 38 | 39 | ..\KanColleCacher\Libraries\KanColleWrapper.dll 40 | 41 | 42 | ..\KanColleCacher\Libraries\Livet.dll 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | ConfigParser.cs 61 | 62 | 63 | GMTHelper.cs 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 81 | -------------------------------------------------------------------------------- /DebugPlatform/GraphList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Grabacr07.KanColleWrapper; 7 | using Grabacr07.KanColleWrapper.Models; 8 | using Grabacr07.KanColleWrapper.Models.Raw; 9 | using Fiddler; 10 | using System.IO; 11 | using Debug = System.Diagnostics.Debug; 12 | //using System.Runtime.Serialization.Json; 13 | using System.Windows; 14 | 15 | 16 | namespace d_f_32.KanColleCacher 17 | { 18 | class GraphList 19 | { 20 | 21 | public static void DebugFunc() 22 | { 23 | GenerateList(); 24 | } 25 | 26 | static List graphList = new List(); 27 | 28 | /// 29 | /// 将解析完成的信息保存到本地 30 | /// 31 | static void PrintToFile() 32 | { 33 | //string filepath = Settings.Current.CacheFolder + "\\GraphList.txt"; 34 | string filepath = @"E:\Game\KanColleViewer ver.3.3\MyCache\GraphList.txt"; 35 | StringBuilder content = new StringBuilder(); 36 | 37 | content.AppendFormat( 38 | "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\r\n", 39 | "SortNo", "ShipId", "ShipName", 40 | "FileName", "FileVersion", 41 | "TypeName", "TypeId" 42 | ); 43 | content.AppendFormat( 44 | "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\r\n", 45 | "序号", "ID", "名称", 46 | "文件名", "文件版本", "文件序号", 47 | "类型", "类型序号", "类型ID" 48 | ); 49 | try 50 | { 51 | graphList.Sort((x, y) => 52 | { 53 | if (x.ship_sortno == y.ship_sortno) 54 | { 55 | if (x.ship_id == y.ship_id) 56 | return 0; 57 | 58 | return x.ship_id < y.ship_id ? -1 : 1; 59 | } 60 | 61 | return x.ship_sortno < y.ship_sortno ? -1 : 1; 62 | }); 63 | } 64 | catch (Exception ex) 65 | { 66 | Debug.WriteLine("Cachr> GraphList.PrintToFile() 排序时发生异常(graphList.Sort)"); 67 | Debug.WriteLine(ex); 68 | } 69 | 70 | 71 | graphList.ForEach(x => 72 | { 73 | content.AppendFormat( 74 | "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\r\n", 75 | x.ship_sortno, x.ship_id, x.ship_name, 76 | x.ship_filename, x.ship_version, 77 | x.ship_type_name, x.ship_type_id 78 | ); 79 | }); 80 | 81 | try 82 | { 83 | File.WriteAllText(filepath, content.ToString()); 84 | } 85 | catch (Exception ex) 86 | { 87 | //Log.Exception(ex.Source, ex, "写入立绘列表文件时异常"); 88 | } 89 | } 90 | 91 | /// 92 | /// 解析 api_start2 数据信息 93 | /// 94 | static void ParseSession(Session oSession) 95 | { 96 | SvData svd; 97 | if (!SvData.TryParse(oSession, out svd)) 98 | { 99 | //Log.Warning("GraphList.ParseSession()", "TryParse失败,无效的Session对象!"); 100 | return; 101 | } 102 | 103 | var mst_shipgraph = svd.Data.api_mst_shipgraph 104 | .ToDictionary(x => x.api_id); 105 | var mst_ship = svd.Data.api_mst_ship 106 | .ToDictionary(x => x.api_id); 107 | var mst_stype = svd.Data.api_mst_stype 108 | .ToDictionary(x => x.api_id); 109 | 110 | graphList.Clear(); 111 | 112 | foreach (var _pair in mst_shipgraph) 113 | { 114 | var item = new ship_graph_item(); 115 | var _loc1 = _pair.Value; 116 | 117 | item.ship_id = _loc1.api_id; 118 | item.ship_filename = _loc1.api_filename; 119 | item.ship_version = _loc1.api_version; 120 | item.ship_graph_sortno = _loc1.api_sortno; 121 | 122 | if (mst_ship.ContainsKey(item.ship_id)) 123 | { 124 | var _loc2 = mst_ship[item.ship_id]; 125 | 126 | item.ship_sortno = _loc2.api_sortno; 127 | item.ship_name = _loc2.api_name; 128 | item.ship_type_id = _loc2.api_stype; 129 | 130 | if (mst_stype.ContainsKey(item.ship_type_id)) 131 | { 132 | var _loc3 = mst_stype[item.ship_type_id]; 133 | item.ship_type_name = _loc3.api_name; 134 | item.ship_type_sortno = _loc3.api_sortno; 135 | } 136 | 137 | graphList.Add(item); 138 | mst_ship.Remove(item.ship_id); 139 | } 140 | else 141 | { 142 | #if DEBUG 143 | Debug.WriteLine(@"CACHR> shipgraph->ship匹配失败 144 | > {0} = {1} {2} {3} 145 | ", _loc1.ToString(), _loc1.api_id, _loc1.api_sortno, _loc1.api_filename); 146 | #endif 147 | } 148 | } 149 | 150 | #if DEBUG 151 | Debug.WriteLine("CACHR> graphList = {0}, mst_shipgraph = {1}", 152 | graphList.Count.ToString(), 153 | mst_shipgraph.Count.ToString() 154 | ); 155 | #endif 156 | } 157 | 158 | /// 159 | /// 开始生成 GraphList.txt 文件 160 | /// 161 | static public void GenerateList() 162 | { 163 | //var path = Settings.Current.CacheFolder + "\\api_start2.session"; 164 | var path = @"E:\Game\KanColleViewer ver.3.3\MyCache\api_start2.session"; 165 | if (!File.Exists(path)) 166 | { 167 | MessageBox.Show("无法生成舰娘列表,因为没有保存 api_start2 通信数据。", "提督很忙!缓存工具"); 168 | return; 169 | } 170 | 171 | //kcsapi_start2 data; 172 | Session oSession; 173 | //try 174 | //{ 175 | //data = (kcsapi_start2)ReadSessionData(); 176 | oSession = ReadSessionData(path) as Session; 177 | //} 178 | //catch (Exception ex) 179 | //{ 180 | // MessageBox.Show("未能生成舰娘列表。读取本地保存的 api_start2 通信数据时发生异常。", "提督很忙!缓存工具"); 181 | // //Log.Exception(ex.Source, ex, "读取本地保存的 api_start2 通信数据时发生异常"); 182 | // throw ex; 183 | //} 184 | try 185 | { 186 | ParseSession(oSession); 187 | } 188 | catch (Exception ex) 189 | { 190 | MessageBox.Show("未能生成舰娘列表。解析 api_start2 数据时发生异常。", "提督很忙!缓存工具"); 191 | //Log.Exception(ex.Source, ex, "解析 api_start2 数据时发生异常。"); 192 | return; 193 | } 194 | try 195 | { 196 | PrintToFile(); 197 | 198 | //string filepath = Settings.Current.CacheFolder + "\\GraphList.txt"; 199 | string filepath = @"E:\Game\KanColleViewer ver.3.3\MyCache\GraphList.txt"; 200 | var si = new System.Diagnostics.ProcessStartInfo() 201 | { 202 | FileName = filepath, 203 | UseShellExecute = true, 204 | }; 205 | System.Diagnostics.Process.Start(si); 206 | } 207 | catch (Exception ex) 208 | { 209 | //Log.Exception(ex.Source, ex, "写入GraphList.txt时或启动进程时发生异常"); 210 | return; 211 | } 212 | } 213 | 214 | /// 215 | /// 保存 api_start2 通信数据到本地 216 | /// 217 | static void SaveSessionData(Session session) 218 | { 219 | //var path = Settings.Current.CacheFolder + "\\api_start2.dat"; 220 | 221 | session.SaveSession(Settings.Current.CacheFolder + "\\api_start2.session", false); 222 | 223 | //var data = session.GetRequestBodyAsString(); 224 | //data = data.StartsWith("svdata=") 225 | // ? data.Substring(7) : data.Replace("svdata=", ""); 226 | 227 | //Debug.WriteLineIf(data.Length < 100, data); 228 | 229 | //File.WriteAllText(path, data); 230 | } 231 | 232 | /// 233 | /// 从本地读取 api_start2 通信数据 234 | /// 235 | static object ReadSessionData(string path) 236 | { 237 | //var path = Settings.Current.CacheFolder + "\\api_start2.dat"; 238 | //var bytes = Encoding.UTF8.GetBytes(File.ReadAllText(path)); 239 | 240 | //var serializer = new DataContractJsonSerializer(typeof(svdata)); 241 | //using (var stream = new MemoryStream(bytes)) 242 | //{ 243 | // return serializer.ReadObject(stream) as svdata; 244 | //} 245 | 246 | Session session = new Session(new byte[] { 0 }, new byte[] { 0 }); 247 | if (!session.LoadRequestBodyFromFile(path)) 248 | { 249 | throw new ApplicationException("LoadRequestBodyFromFile Failed!! " + path); 250 | } 251 | if (!session.LoadResponseFromFile(path)) 252 | { 253 | throw new ApplicationException("LoadResponseFromFile Failed!! " + path); 254 | } 255 | return session; 256 | } 257 | 258 | /// 259 | /// Fiddler规则(通信完成后 260 | /// 261 | static public void RulePrintGraphList(Session oSession) 262 | { 263 | if (oSession.PathAndQuery != "/kcsapi/api_start2") 264 | return; 265 | 266 | //Debug.WriteLine("【START2】" + oSession.PathAndQuery); 267 | 268 | SaveSessionData(oSession); 269 | 270 | //移除规则 271 | RemoveRule(); 272 | } 273 | 274 | static public void AppendRule() 275 | { 276 | FiddlerApplication.AfterSessionComplete += RulePrintGraphList; 277 | //Debug.WriteLine("CACHR> RulePrintGraphList Appended"); 278 | } 279 | 280 | static public void RemoveRule() 281 | { 282 | FiddlerApplication.AfterSessionComplete -= RulePrintGraphList; 283 | //Debug.WriteLine("CACHR> RulePrintGraphList Removed"); 284 | } 285 | } 286 | 287 | 288 | class ship_graph_item 289 | { 290 | public int ship_id = 0; 291 | public int ship_sortno = 0; 292 | public string ship_name = ""; 293 | 294 | public int ship_type_id = 0; 295 | public int ship_type_sortno = 0; 296 | public string ship_type_name = ""; 297 | 298 | public int ship_graph_sortno = 0; 299 | public string ship_filename = ""; 300 | public string ship_version = ""; 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /DebugPlatform/Last-Modified - 副本.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | /kcs/scenes/TitleMain.swf 4 | /kcs/PortMain.swf 5 | /kcs/resources/swf/commonAssets.swf 6 | /kcs/resources/swf/font.swf 7 | /kcs/resources/swf/icons.swf 8 | /kcs/resources/swf/sound_se.swf 9 | /kcs/scenes/ArsenalMain.swf 10 | /kcs/scenes/DutyMain.swf 11 | /kcs/scenes/OrganizeMain.swf 12 | /kcs/scenes/RemodelMain.swf 13 | /kcs/scenes/RepairMain.swf 14 | /kcs/scenes/SupplyMain.swf 15 | 16 | -------------------------------------------------------------------------------- /DebugPlatform/Last-Modified.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | /kcs/PortMain.swf 5 | 6 | 7 | 8 | 9 | /kcs/resources/swf/commonAssets.swf 10 | 11 | 12 | 13 | 14 | /kcs/resources/swf/font.swf 15 | 16 | 17 | 18 | 19 | /kcs/resources/swf/icons.swf 20 | 21 | 22 | 23 | 24 | /kcs/resources/swf/sound_se.swf 25 | 26 | 27 | 28 | 29 | /kcs/scenes/ArsenalMain.swf 30 | 31 | 32 | 33 | 34 | /kcs/scenes/DutyMain.swf 35 | 36 | 37 | 38 | 39 | /kcs/scenes/OrganizeMain.swf 40 | 41 | 42 | 43 | 44 | /kcs/scenes/RemodelMain.swf 45 | 46 | 47 | 48 | 49 | /kcs/scenes/RepairMain.swf 50 | 51 | 52 | 53 | 54 | /kcs/scenes/SupplyMain.swf 55 | 56 | 57 | 58 | 59 | /kcs/scenes/TitleMain.swf 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /DebugPlatform/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Data; 7 | using System.Windows; 8 | //using System.Text.RegularExpressions; 9 | 10 | using System.Xml; 11 | using System.Xml.Linq; 12 | using System.IO; 13 | 14 | using d_f_32.KanColleCacher; 15 | using d_f_32.KanColleCacher.Configuration; 16 | 17 | namespace DebugPlatform 18 | { 19 | class Program 20 | { 21 | 22 | static void Main(string[] args) 23 | { 24 | Console.WriteLine("-----------------------------------------"); 25 | GraphList.DebugFunc(); 26 | Console.ReadLine(); 27 | } 28 | static void Main_old(string[] args) 29 | { 30 | Console.WriteLine("-----------------------------------------"); 31 | Console.WriteLine("KanColleCacher_1.3_Updater Copyright d.f.32 - 2015 \n"); 32 | Console.WriteLine("本程序是KCV缓存插件 KanColleCacher 的更新补丁程序。"); 33 | Console.WriteLine("插件从1.3更新到2.0时废弃了原有的设置文件与部分数据文件的储存方式,这将造成设置的丢失以及部分缓存文件需要重新下载。"); 34 | Console.WriteLine("本程序则是用来解决这一问题的。"); 35 | Console.WriteLine(); 36 | Console.WriteLine(@"在程序运行前,请核实以下描述: 37 | * 你在使用名为【舰队很忙!KanColleViewer】的游戏程序 38 | * 你安装使用了插件 KanColleCacher 一段时间,插件为你缓存了大量的游戏文件 39 | * 你需要将插件 KanColleCacher 从1.3更新到2.0,且不希望再次这些下载缓存文件 40 | * 你知道本程序只是补丁,并不包含插件主体的dll文件,且也不会为你拷贝移动插件主体 41 | * 你已经在运行前将本程序放置在了【舰队很忙!KanColleViewer】的程序目录下,或其目录的Plugins子目录下 42 | 43 | 若以上描述核实无误,请按回车键以开始执行补丁..."); 44 | Console.ReadLine(); 45 | 46 | List setFiles = new List(); 47 | List cacheFolders = new List(); 48 | string dir = Directory.GetCurrentDirectory(); 49 | 50 | Console.WriteLine("-----------------------------------------"); 51 | Console.WriteLine("检索设置文件..."); 52 | 53 | var path = dir + @"\Plugins\KanColleCacher.xml"; 54 | if (File.Exists(path)) setFiles.Add(path); 55 | 56 | path = dir + @"\KanColleCacher.xml"; 57 | if (File.Exists(path)) setFiles.Add(path); 58 | 59 | path = Path.Combine( 60 | Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), 61 | "grabacr.net", 62 | "KanColleViewer", 63 | "KanColleCacher.xml" 64 | ); 65 | if (File.Exists(path)) setFiles.Add(path); 66 | 67 | if (setFiles.Count == 0) 68 | { 69 | Console.WriteLine("没有找到任何设置文件!更新无法继续进行。"); 70 | Console.WriteLine("请按下回车键以退出程序..."); 71 | Console.ReadLine(); 72 | return; 73 | } 74 | 75 | Console.WriteLine("找到设置文件共 {0} 个",setFiles.Count); 76 | 77 | foreach (var fpath in setFiles) 78 | { 79 | Console.WriteLine("处理设置文件...\n\t" + fpath); 80 | try 81 | { 82 | string cachefolder; 83 | ProcessSettingFile(fpath, out cachefolder); 84 | if (String.IsNullOrEmpty(cachefolder) || !Directory.Exists(cachefolder)) 85 | { 86 | Console.WriteLine("无效的缓存文件夹!\n\t" + cachefolder); 87 | } 88 | cacheFolders.Add(cachefolder); 89 | } 90 | catch (Exception ex) 91 | { 92 | Console.WriteLine("处理设置文件时发生异常。可能是文件损坏。"); 93 | Console.WriteLine(ex.Message); 94 | } 95 | } 96 | 97 | Console.WriteLine("设置文件处理结束。找到缓存文件夹 {0} 个", cacheFolders.Count); 98 | Console.WriteLine(); 99 | Console.WriteLine("-----------------------------------------"); 100 | 101 | if (cacheFolders.Count == 0) 102 | { 103 | Console.WriteLine("没有找到任何缓存文件夹的设置!更新无法继续进行。"); 104 | Console.WriteLine("请手动输入缓存文件夹地址或按回车键结束程序:"); 105 | string input; 106 | while (!String.IsNullOrWhiteSpace(input = Console.ReadLine())) 107 | { 108 | if (Directory.Exists(input)) 109 | { 110 | cacheFolders.Add(input); 111 | break; 112 | } 113 | Console.WriteLine("无效地址"); 114 | } 115 | if (cacheFolders.Count==0) return; 116 | } 117 | 118 | Console.WriteLine(); 119 | 120 | foreach (var folder in cacheFolders) 121 | { 122 | Console.WriteLine("处理缓存文件夹...\n\t" + folder); 123 | ProcessCacheFolder(folder); 124 | } 125 | 126 | Console.WriteLine("缓存文件处理结束\n"); 127 | Console.WriteLine("-----------------------------------------"); 128 | Console.WriteLine("是否移除废弃的文件? [Y] 删除 [N] 不删除"); 129 | 130 | string ipt = Console.ReadLine().ToLower(); 131 | while (!ipt.StartsWith("y") && !ipt.StartsWith("n")) 132 | { 133 | ipt = Console.ReadLine().ToLower(); 134 | } 135 | 136 | if (ipt.StartsWith("y")) 137 | { 138 | foreach (var f in setFiles) 139 | { 140 | try { 141 | File.Delete(f); 142 | Console.WriteLine("删除 " + f); 143 | } 144 | catch { } 145 | } 146 | foreach (var p in cacheFolders) 147 | { 148 | try { 149 | File.Delete(p + "\\Last-Modified.xml"); 150 | Console.WriteLine("删除 " + p + "\\Last-Modified.xml"); 151 | } 152 | catch { } 153 | } 154 | } 155 | 156 | Console.WriteLine("按任意键退出程序"); 157 | Console.ReadKey(); 158 | } 159 | 160 | static void ProcessSettingFile(string filepath, out string cachefolder) 161 | { 162 | var doc = XDocument.Load(filepath); 163 | var parser = new ConfigParser(); 164 | var section = parser["Settings"] = new Section(); 165 | parser.SerializeObject(new Settings(), "Settings"); 166 | 167 | foreach (var elm in doc.Root.Elements()) 168 | { 169 | var name = elm.Name.ToString(); 170 | var val = elm.Value; 171 | 172 | if (!String.IsNullOrEmpty(val)) 173 | { 174 | section[name] = val; 175 | } 176 | } 177 | 178 | section["SaveApiStart2"] = section["PrintGraphList"]; 179 | section["PrintGraphList"] = null; 180 | 181 | parser.SaveIniFile(filepath.Substring(0, filepath.Length - 3) + "ini"); 182 | cachefolder = section["CacheFolder"]; 183 | } 184 | 185 | static void ProcessCacheFolder(string cachefolder) 186 | { 187 | var xmlf = cachefolder + "//Last-Modified.xml"; 188 | 189 | if (!File.Exists(xmlf)) 190 | { 191 | Console.WriteLine("没有找到Last-Modified.xml。"); 192 | return; 193 | } 194 | XDocument doc; 195 | try 196 | { 197 | doc = XDocument.Load(xmlf); 198 | } 199 | catch (Exception) 200 | { 201 | Console.WriteLine("Last-Modified.xml文件损坏。"); 202 | return; 203 | } 204 | 205 | int count = 0; 206 | foreach (var elm in doc.Root.Elements()) 207 | { 208 | count++; 209 | try 210 | { 211 | var path = elm.Element("Path").Value; 212 | var time = elm.Element("Time").Value; 213 | 214 | path = (cachefolder + "\\" + path).Replace('/', '\\'); 215 | if (!File.Exists(path)) 216 | { 217 | Console.WriteLine("无效地址:" + path); 218 | continue; 219 | } 220 | 221 | var fi = new FileInfo(path); 222 | fi.LastWriteTime =GMTHelper.GMT2Local(time); 223 | } 224 | catch(Exception ex) 225 | { 226 | Console.WriteLine("第 {0} 个元素损坏。" + ex.Message, count); 227 | } 228 | } 229 | Console.WriteLine("Last-Modified.xml 处理结束,共处理 {0} 个文件", count); 230 | } 231 | } 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | class ModifiedRecord 240 | { 241 | static string filepath; 242 | static XDocument fileXML; 243 | static IEnumerable recordList; 244 | 245 | const string _RootName = "Last-Modified"; 246 | const string _ItemElm = "Record"; 247 | const string _ElmPath = "Path"; 248 | const string _ElmTime = "Time"; 249 | const string _ElmVersion = "Version"; 250 | 251 | #region 加载与保存 252 | 253 | /// 254 | /// 从Last-Modified.xml加载记录 255 | /// 256 | static public void Load() 257 | { 258 | //filepath = Settings.Current.CacheFolder + "\\Last-Modified.xml"; 259 | filepath = @"B:\GitHub\KanColleCacher\DebugPlatform\Last-Modified - 副本.xml"; 260 | try 261 | { 262 | if (File.Exists(filepath)) 263 | fileXML = XDocument.Load(filepath); 264 | } 265 | catch (Exception ex) 266 | { 267 | //Log.Exception(ex.InnerException, ex, "加载Last-Modified.xml时发生异常"); 268 | throw ex; 269 | } 270 | 271 | if (fileXML == null) 272 | { 273 | fileXML = new XDocument(); 274 | fileXML.Add(new XElement(_RootName)); 275 | } 276 | 277 | recordList = fileXML.Descendants(_ItemElm); 278 | //recordList 和 fileXML是同步的 279 | } 280 | 281 | /// 282 | /// 保存到Last-Modified.xml 283 | /// 284 | static public void Save() 285 | { 286 | filepath = @"B:\GitHub\KanColleCacher\DebugPlatform\Last-Modified.xml"; 287 | 288 | 289 | 290 | try 291 | { 292 | var elms = fileXML.Descendants(_ItemElm) 293 | .OrderBy(elm => 294 | { return elm.Element(_ElmPath).Value; } 295 | ).ToArray(); 296 | 297 | fileXML.Root.Elements().Remove(); 298 | fileXML.Root.Add(elms); 299 | } 300 | catch 301 | { 302 | //Log.Exception(ex.InnerException, ex, "保存Last-Modified.xml时发生异常"); 303 | } 304 | 305 | fileXML.Save(filepath); 306 | } 307 | 308 | } 309 | #endregion 310 | 311 | 312 | 313 | } 314 | -------------------------------------------------------------------------------- /DebugPlatform/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的常规信息通过以下 6 | // 特性集控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("KanColleCacher_1.3_Updater")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("KanColleCacher")] 13 | [assembly: AssemblyCopyright("Copyright © d.f.32 - 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 使此程序集中的类型 18 | // 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 19 | // 则将该类型上的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("5fd4a204-ab3a-4460-a561-027d88009494")] 24 | 25 | // 程序集的版本信息由下面四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /DebugPlatform/Settings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Debug = System.Diagnostics.Debug; 8 | using d_f_32.KanColleCacher.Configuration; 9 | using System.ComponentModel; 10 | using System.ComponentModel.Composition; 11 | using System.Runtime.CompilerServices; 12 | 13 | 14 | namespace d_f_32.KanColleCacher 15 | { 16 | [Serializable] 17 | public class Settings : INotifyPropertyChanged 18 | { 19 | private static string filePath; 20 | 21 | public static Settings Current { get; private set; } 22 | 23 | /// 24 | /// 加载插件设置 25 | /// 26 | public static void Load() 27 | { 28 | filePath = Directory.GetCurrentDirectory() + @"\Plugins\KanColleCacher.ini"; 29 | 30 | if (!File.Exists(filePath)) 31 | { 32 | var path = Path.Combine( 33 | Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), 34 | "grabacr.net", 35 | "KanColleViewer", 36 | "KanColleCacher.ini" 37 | ); 38 | if (File.Exists(path)) 39 | filePath = path; 40 | } 41 | 42 | if (File.Exists(filePath)) 43 | { 44 | var _Parser = ConfigParser.ReadIniFile(filePath); 45 | Current = _Parser.DeserializeObject("Settings"); 46 | 47 | try 48 | { 49 | Directory.CreateDirectory(Current.CacheFolder); 50 | } 51 | catch (Exception ex) 52 | { 53 | Current.CacheFolder = Directory.GetCurrentDirectory() + @"\MyCache"; 54 | //Log.Exception(ex.InnerException, ex, "设置文件中CacheFolder不存在,试图创建时发生异常"); 55 | } 56 | } 57 | else 58 | { 59 | //设置文件丢失 60 | } 61 | 62 | Current = Current ?? new Settings(); 63 | } 64 | 65 | /// 66 | /// 保存设置 67 | /// 68 | public static void Save() 69 | { 70 | try 71 | { 72 | var _Parser = File.Exists(filePath) 73 | ? ConfigParser.ReadIniFile(filePath) 74 | : new ConfigParser(); 75 | 76 | _Parser.SerializeObject(Current, "Settings"); 77 | _Parser.SaveIniFile(filePath); 78 | } 79 | catch (Exception ex) 80 | { 81 | //Log.Exception(ex.InnerException, ex, "保存设置文件时出现异常"); 82 | } 83 | } 84 | 85 | 86 | public Settings () 87 | { 88 | _CacheFolder = Directory.GetCurrentDirectory() + @"\MyCache"; 89 | _CacheEnabled = true; 90 | _HackEnabled = true; 91 | _HackTitleEnabled = true; 92 | 93 | _CacheEntryFiles = 2; 94 | _CachePortFiles = 2; 95 | _CacheSceneFiles = 2; 96 | _CacheResourceFiles = 2; 97 | _CacheSoundFiles = 2; 98 | 99 | _CheckFiles = 1; 100 | _SaveApiStart2 = true; 101 | } 102 | 103 | 104 | 105 | private string _CacheFolder; 106 | [ExportMetadata("Comment","缓存文件夹")] 107 | public string CacheFolder 108 | { 109 | get { return this._CacheFolder; } 110 | set 111 | { 112 | if (this._CacheFolder != value) 113 | { 114 | this._CacheFolder = value; 115 | this.RaisePropertyChanged(); 116 | } 117 | } 118 | } 119 | 120 | private bool _CacheEnabled; 121 | [ExportMetadata("Comment", "启用缓存功能")] 122 | public bool CacheEnabled 123 | { 124 | get { return this._CacheEnabled; } 125 | set 126 | { 127 | if (this._CacheEnabled != value) 128 | { 129 | this._CacheEnabled = value; 130 | this.RaisePropertyChanged(); 131 | } 132 | } 133 | } 134 | 135 | private bool _HackEnabled; 136 | [ExportMetadata("Comment", "启用Hack规则")] 137 | public bool HackEnabled 138 | { 139 | get { return this._HackEnabled; } 140 | set 141 | { 142 | if (this._HackEnabled != value) 143 | { 144 | this._HackEnabled = value; 145 | this.RaisePropertyChanged(); 146 | } 147 | } 148 | } 149 | 150 | private bool _HackTitleEnabled; 151 | [ExportMetadata("Comment", "启用针对TitleCall与WorldName的特殊规则")] 152 | public bool HackTitleEnabled 153 | { 154 | get { return this._HackTitleEnabled; } 155 | set 156 | { 157 | if (this._HackTitleEnabled != value) 158 | { 159 | this._HackTitleEnabled = value; 160 | this.RaisePropertyChanged(); 161 | } 162 | } 163 | } 164 | 165 | private int _CacheEntryFiles; 166 | public int CacheEntryFiles 167 | { 168 | get { return this._CacheEntryFiles; } 169 | set 170 | { 171 | if (this._CacheEntryFiles != value) 172 | { 173 | this._CacheEntryFiles = value; 174 | this.RaisePropertyChanged(); 175 | } 176 | } 177 | } 178 | 179 | private int _CachePortFiles; 180 | public int CachePortFiles 181 | { 182 | get { return this._CachePortFiles; } 183 | set 184 | { 185 | if (this._CachePortFiles != value) 186 | { 187 | this._CachePortFiles = value; 188 | this.RaisePropertyChanged(); 189 | } 190 | } 191 | } 192 | 193 | private int _CacheSceneFiles; 194 | public int CacheSceneFiles 195 | { 196 | get { return this._CacheSceneFiles; } 197 | set 198 | { 199 | if (this._CacheSceneFiles != value) 200 | { 201 | this._CacheSceneFiles = value; 202 | this.RaisePropertyChanged(); 203 | } 204 | } 205 | } 206 | 207 | private int _CacheResourceFiles; 208 | public int CacheResourceFiles 209 | { 210 | get { return this._CacheResourceFiles; } 211 | set 212 | { 213 | if (this._CacheResourceFiles != value) 214 | { 215 | this._CacheResourceFiles = value; 216 | this.RaisePropertyChanged(); 217 | } 218 | } 219 | } 220 | 221 | private int _CacheSoundFiles; 222 | public int CacheSoundFiles 223 | { 224 | get { return this._CacheSoundFiles; } 225 | set 226 | { 227 | if (this._CacheSoundFiles != value) 228 | { 229 | this._CacheSoundFiles = value; 230 | this.RaisePropertyChanged(); 231 | } 232 | } 233 | } 234 | 235 | private int _CheckFiles; 236 | [ExportMetadata("Comment", @"向服务器发送文件验证请求 237 | ; 0 - 不验证;1 - 不验证资源SWF文件;2 - 验证所有SWF文件 238 | ; 验证文件可以保证缓存的游戏文件始终是有效可用的,但因为要与服务器通信所以会比不验证花费更长的加载时间")] 239 | public int CheckFiles 240 | { 241 | get { return this._CheckFiles; } 242 | set 243 | { 244 | if (this._CheckFiles != value) 245 | { 246 | this._CheckFiles = value; 247 | this.RaisePropertyChanged(); 248 | } 249 | } 250 | } 251 | 252 | private bool _SaveApiStart2; 253 | [ExportMetadata("Comment", @"保存 api_start2 通信数据以便生成 舰娘立绘的文件名列表。 254 | ; 只有当缓存文件夹中的 api_start2.dat 不存在时才会进行保存。 255 | ; 这一设置只有在游戏加载时才有效。")] 256 | public bool SaveApiStart2 257 | { 258 | get { return this._SaveApiStart2; } 259 | set 260 | { 261 | if (this._SaveApiStart2 != value) 262 | { 263 | this._SaveApiStart2 = value; 264 | this.RaisePropertyChanged(); 265 | } 266 | } 267 | } 268 | 269 | #region 实现通知 270 | 271 | public event PropertyChangedEventHandler PropertyChanged; 272 | 273 | void RaisePropertyChanged([CallerMemberName] String propertyName = "") 274 | { 275 | if (PropertyChanged != null) 276 | { 277 | PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 278 | } 279 | } 280 | 281 | #endregion 282 | } 283 | } 284 | -------------------------------------------------------------------------------- /KanColleCacher.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Express 2013 for Windows Desktop 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KanColleCacher", "KanColleCacher\KanColleCacher.csproj", "{1FF4CF0A-E57E-433C-B5B0-5363C2425780}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DebugPlatform", "DebugPlatform\DebugPlatform.csproj", "{D8F14FD8-B541-40B0-9D52-32FF0A7EB6B3}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {1FF4CF0A-E57E-433C-B5B0-5363C2425780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {1FF4CF0A-E57E-433C-B5B0-5363C2425780}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {1FF4CF0A-E57E-433C-B5B0-5363C2425780}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {1FF4CF0A-E57E-433C-B5B0-5363C2425780}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {D8F14FD8-B541-40B0-9D52-32FF0A7EB6B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {D8F14FD8-B541-40B0-9D52-32FF0A7EB6B3}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {D8F14FD8-B541-40B0-9D52-32FF0A7EB6B3}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {D8F14FD8-B541-40B0-9D52-32FF0A7EB6B3}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /KanColleCacher/CacheCore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using Debug = System.Diagnostics.Debug; 8 | 9 | 10 | namespace d_f_32.KanColleCacher 11 | { 12 | 13 | enum filetype 14 | { 15 | not_file, 16 | unknown_file, 17 | 18 | game_entry, //kcs\mainD2.swf 19 | //kcs\Core.swf 20 | 21 | entry_large, //kcs\scenes\TitleMain.swf 22 | //kcs\resources\swf\commonAsset.swf 23 | //kcs\resources\swf\font.swf 24 | //kcs\resources\swf\icons.swf 25 | 26 | port_main, //kcs\PortMain.swf 27 | //kcs\resources\swf\sound_se.swf 28 | 29 | scenes, //kcs\scenes\ 30 | 31 | resources, //kcs\resources\bgm_p\ 32 | //kcs\resources\swf\sound_bgm.swf 33 | //kcs\resources\swf\sound_b_bgm_*.swf 34 | //kcs\resources\swf\map\ 35 | //kcs\resources\swf\ships\ 36 | 37 | image, //kcs\resources\images 38 | sound, //kcs\sound 39 | 40 | world_name, //kcs\resources\images\world 41 | title_call, //kcs\sound\titlecall 42 | } 43 | 44 | 45 | class CacheCore 46 | { 47 | #region 初始化与析构 48 | Settings set; 49 | string myCacheFolder; 50 | 51 | public CacheCore() 52 | { 53 | set = Settings.Current; 54 | //VersionChecker.Load(); 55 | myCacheFolder = set.CacheFolder; 56 | } 57 | 58 | 59 | #endregion 60 | 61 | /// 62 | /// 对于一个新的客户端请求,根据url,决定下一步要对请求怎样处理 63 | /// 64 | /// 请求的url 65 | /// 本地文件地址 or 记录的修改日期 66 | /// 下一步我们该做什么?忽略请求;返回缓存文件;验证缓存文件 67 | public Direction GotNewRequest(string url, out string result) 68 | { 69 | result = ""; 70 | string filepath = ""; 71 | 72 | Uri uri; 73 | try { uri = new Uri(url); } 74 | catch (Exception ex) 75 | { 76 | System.Diagnostics.Debug.WriteLine(ex); 77 | return Direction.Discharge_Response; 78 | //url无效,忽略请求(不进行任何操作) 79 | } 80 | 81 | if (!uri.IsFilePath()) 82 | { 83 | return Direction.Discharge_Response; 84 | //url非文件,忽略请求 85 | } 86 | 87 | //识别文件类型 88 | filetype type = _RecognizeFileType(uri); 89 | if (type == filetype.unknown_file || 90 | type == filetype.not_file || 91 | type == filetype.game_entry) 92 | { 93 | return Direction.Discharge_Response; 94 | //无效的文件,忽略请求 95 | } 96 | 97 | //检查Title Call与World Name的特殊地址 98 | if (set.HackTitleEnabled) 99 | { 100 | if (type == filetype.title_call) 101 | { 102 | filepath = uri.AbsolutePath.Replace('/', '\\'); 103 | filepath = filepath.Remove(filepath.LastIndexOf('\\')) + ".mp3"; 104 | filepath = myCacheFolder + filepath; 105 | result = filepath; 106 | 107 | if (File.Exists(filepath)) 108 | return Direction.Return_LocalFile; 109 | } 110 | else if (type == filetype.world_name) 111 | { 112 | filepath = myCacheFolder + @"\kcs\resources\image\world.png"; 113 | result = filepath; 114 | 115 | if (File.Exists(filepath)) 116 | return Direction.Return_LocalFile; 117 | } 118 | } 119 | 120 | //检查一般文件地址 121 | if ((type == filetype.resources && set.CacheResourceFiles > 0) || 122 | (type == filetype.entry_large && set.CacheEntryFiles > 0) || 123 | (type == filetype.port_main && set.CachePortFiles > 0) || 124 | (type == filetype.scenes && set.CacheSceneFiles > 0) || 125 | (type == filetype.sound && set.CacheSoundFiles > 0) || 126 | ((type == filetype.title_call || 127 | type == filetype.world_name || 128 | type == filetype.image) && set.CacheResourceFiles > 0)) 129 | { 130 | filepath = myCacheFolder + uri.AbsolutePath.Replace('/', '\\'); 131 | 132 | //检查Hack文件地址 133 | if (set.HackEnabled) 134 | { 135 | var fnext = uri.Segments.Last().Split('.'); 136 | string hfilepath = filepath.Replace(uri.Segments.Last(), fnext[0] + ".hack." + fnext.Last()); 137 | 138 | if (File.Exists(hfilepath)) 139 | { 140 | result = hfilepath; 141 | return Direction.Return_LocalFile; 142 | //存在hack文件,则返回本地文件 143 | } 144 | 145 | } 146 | 147 | //检查缓存文件 148 | if (File.Exists(filepath)) 149 | { 150 | //存在本地缓存文件 -> 检查文件的最后修改时间 151 | //(验证所有文件 或 只验证非资源文件) 152 | if (set.CheckFiles > 1 || (set.CheckFiles > 0 && type != filetype.resources)) 153 | { 154 | //只有swf文件需要验证时间 155 | if (filepath.EndsWith(".swf")) 156 | { 157 | //文件存在且需要验证时间 158 | //-> 请求服务器验证修改时间(记录读取和保存的位置) 159 | result = filepath; 160 | _RecordTask(url, filepath); 161 | return Direction.Verify_LocalFile; 162 | } 163 | 164 | ////检查文件时间 165 | //int i = VersionChecker.GetFileLastTime(uri, out result); 166 | 167 | //if (i == 1) 168 | //{ 169 | // //存在这个文件的修改时间记录 170 | // //-> 请求服务器验证修改时间(记录读取和保存的位置) 171 | // _RecordTask(url, filepath); 172 | // return Direction.Verify_LocalFile; 173 | //} 174 | //else if (i == 0) 175 | //{ 176 | // //没有关于这个文件最后修改时间的记录 177 | // //-> 当做这个文件不存在 178 | // //-> 下载文件(记录保存地址) 179 | // _RecordTask(url, filepath); 180 | // return Direction.Discharge_Response; 181 | //} 182 | //else 183 | //{ 184 | // //文件类型不需要验证时间(只有swf验证) 185 | //} 186 | } 187 | //文件不需验证 188 | //->返回本地缓存文件 189 | result = filepath; 190 | return Direction.Return_LocalFile; 191 | 192 | } 193 | else 194 | { 195 | //缓存文件不存在 196 | //-> 下载文件 (记录保存地址) 197 | _RecordTask(url, filepath); 198 | return Direction.Discharge_Response; 199 | } 200 | } 201 | 202 | //文件类型对应的缓存设置没有开启 203 | //-> 当做文件不存在 204 | return Direction.Discharge_Response; 205 | } 206 | 207 | filetype _RecognizeFileType(Uri uri) 208 | { 209 | if (!uri.IsFilePath()) 210 | return filetype.not_file; 211 | 212 | var seg = uri.Segments; 213 | 214 | if (seg[1] != "kcs/") 215 | { 216 | return filetype.not_file; 217 | } 218 | else 219 | { 220 | 221 | if (seg[2] == "resources/") 222 | { 223 | if (seg[3] == "swf/") 224 | { 225 | if (seg[4] == "commonAssets.swf" || 226 | seg[4] == "font.swf" || 227 | seg[4] == "icons.swf") 228 | { 229 | return filetype.entry_large; 230 | } 231 | 232 | else if (seg[4] == ("sound_se.swf")) 233 | { 234 | return filetype.port_main; 235 | } 236 | } 237 | else if (seg[3] == "image/") 238 | { 239 | if (seg[4] == "world/") 240 | { 241 | return filetype.world_name; 242 | } 243 | 244 | return filetype.image; 245 | } 246 | return filetype.resources; 247 | } 248 | else if (seg[2] == "scenes/") 249 | { 250 | if (seg[3] == "TitleMain.swf") 251 | { 252 | return filetype.entry_large; 253 | } 254 | 255 | return filetype.scenes; 256 | } 257 | else if (seg[2] == "sound/") 258 | { 259 | if (seg[3] == "titlecall/") 260 | { 261 | return filetype.title_call; 262 | } 263 | 264 | return filetype.sound; 265 | } 266 | else 267 | { 268 | if (seg[2] == "Core.swf" || 269 | seg[2] == "mainD2.swf") 270 | { 271 | return filetype.game_entry; 272 | // kcs/mainD2.swf; kcs/Core.swf; 273 | } 274 | else if (seg[2] == "PortMain.swf") 275 | { 276 | return filetype.port_main; 277 | // kcs/PortMain.swf; 278 | 279 | } 280 | } 281 | 282 | //Debug.WriteLine("CACHR> _RecogniseFileType检查到无法识别的文件"); 283 | //Debug.WriteLine(" "+uri.AbsolutePath); 284 | return filetype.unknown_file; 285 | } 286 | 287 | } 288 | 289 | public void RecordNewModifiedTime(string url, string time) 290 | { 291 | Uri uri; 292 | try { uri = new Uri(url); } 293 | catch { return; } 294 | 295 | //VersionChecker.Add(uri, time); 296 | } 297 | 298 | public bool AllowedToSave(filetype type) 299 | { 300 | return (type == filetype.resources && set.CacheResourceFiles > 1) || 301 | (type == filetype.entry_large && set.CacheEntryFiles > 1) || 302 | (type == filetype.port_main && set.CachePortFiles > 1) || 303 | (type == filetype.scenes && set.CacheSceneFiles > 1) || 304 | (type == filetype.sound && set.CacheSoundFiles > 1) || 305 | (type == filetype.title_call || 306 | type == filetype.world_name || 307 | type == filetype.image) && set.CacheResourceFiles > 1; 308 | } 309 | 310 | void _RecordTask(string url, string filepath) 311 | { 312 | TaskRecord.Add(url, filepath); 313 | } 314 | } 315 | } -------------------------------------------------------------------------------- /KanColleCacher/CacherToolView.xaml: -------------------------------------------------------------------------------- 1 |  14 | 15 | 16 | 17 | 18 | 19 | 35 | 47 | 56 | 62 | 77 | 130 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 180 | 181 | 184 | 185 | 186 | 187 | 188 | 189 | 190 |