// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT using System; using System.IO; using ClassicalSharp.Network; namespace Launcher.Patcher { public sealed class ResourceFetcher { public bool Done = false; internal AsyncDownloader downloader; SoundPatcher digPatcher, stepPatcher; const string jarClassicUri = "http://s3.amazonaws.com/Minecraft.Download/versions/c0.30_01c/c0.30_01c.jar"; const string jar162Uri = "http://s3.amazonaws.com/Minecraft.Download/versions/1.6.2/1.6.2.jar"; const string pngTerrainPatchUri = "http://static.classicube.net/terrain-patch.png"; const string pngGuiPatchUri = "http://static.classicube.net/gui.png"; const string digSoundsUri = "http://s3.amazonaws.com/MinecraftResources/sound3/dig/"; const string altDigSoundsUri = "http://s3.amazonaws.com/MinecraftResources/sound3/random/"; const string stepSoundsUri = "http://s3.amazonaws.com/MinecraftResources/newsound/step/"; const string altStepSoundsUri = "http://s3.amazonaws.com/MinecraftResources/sound3/step/"; const string musicUri = "http://s3.amazonaws.com/MinecraftResources/music/"; const string newMusicUri = "http://s3.amazonaws.com/MinecraftResources/newmusic/"; ushort flags; public void DownloadItems(AsyncDownloader downloader, Action setStatus) { this.downloader = downloader; DownloadMusicFiles(); digPatcher = new SoundPatcher(ResourceList.DigSounds, "dig_", "step_cloth1"); digPatcher.FetchFiles(digSoundsUri, altDigSoundsUri, this, DigSoundsExist); stepPatcher = new SoundPatcher(ResourceList.StepSounds, "step_", "classic jar"); stepPatcher.FetchFiles(stepSoundsUri, altStepSoundsUri, this, StepSoundsExist); flags = 0; foreach (var entry in ResourceList.Files) flags |= entry.Value; if ((flags & ResourceList.cMask) != 0) downloader.DownloadData(jarClassicUri, false, "classic_jar"); if ((flags & ResourceList.mMask) != 0) downloader.DownloadData(jar162Uri, false, "162_jar"); if ((flags & ResourceList.gMask) != 0) downloader.DownloadData(pngGuiPatchUri, false, "gui_patch"); if ((flags & ResourceList.tMask) != 0) downloader.DownloadData(pngTerrainPatchUri, false, "terrain_patch"); SetFirstStatus(setStatus); } void DownloadMusicFiles() { string[] files = ResourceList.MusicFiles; for (int i = 0; i < files.Length; i++) { if (musicExists[i]) continue; string baseUri = i < 3 ? musicUri : newMusicUri; string url = baseUri + files[i] + ".ogg"; downloader.DownloadData(url, false, files[i]); } } public void AddDownload(string url, string identifier) { downloader.DownloadData(url, false, identifier); } void SetFirstStatus(Action setStatus) { for (int i = 0; i < musicExists.Length; i++) { if (musicExists[i]) continue; setStatus(MakeNext(ResourceList.MusicFiles[i])); return; } setStatus(MakeNext(FirstItem())); } internal byte[] jarClassic, jar162, pngTerrainPatch, pngGuiPatch; public bool Check(Action setStatus) { if (Done) return true; if (!CheckMusicFiles(setStatus)) return false; if (!digPatcher.CheckDownloaded(this, setStatus)) return false; if (!stepPatcher.CheckDownloaded(this, setStatus)) return false; if (!Download("classic_jar", "classic jar", "1.6.2 jar", ref jarClassic, setStatus)) return false; if (!Download("162_jar", "1.6.2 jar", "gui.png", ref jar162, setStatus)) return false; if (!Download("gui_patch", "gui.png patch", "terrain.png patch", ref pngGuiPatch, setStatus)) return false; if (!Download("terrain_patch", "terrain.png patch", null, ref pngTerrainPatch, setStatus)) return false; Done |= IsDone(); return true; } string FirstItem() { if (!DigSoundsExist) return "dig_cloth1"; if (!StepSoundsExist) return "step_cloth1"; if ((flags & ResourceList.cMask) != 0) return "classic jar"; if ((flags & ResourceList.mMask) != 0) return "1.6.2 jar"; if ((flags & ResourceList.gMask) != 0) return "gui.png patch"; if ((flags & ResourceList.tMask) != 0) return "terrain.png patch"; return "(unknown)"; } bool IsDone() { if (flags == 0) return stepPatcher.Done; if ((flags & ResourceList.tMask) != 0) return pngTerrainPatch != null; if ((flags & ResourceList.gMask) != 0) return pngGuiPatch != null; if ((flags & ResourceList.mMask) != 0) return jar162 != null; if ((flags & ResourceList.cMask) != 0) return jarClassic != null; return true; } bool Download(string identifier, string name, string next, ref byte[] data, Action setStatus) { DownloadedItem item; if (downloader.TryGetItem(identifier, out item)) { Console.WriteLine("got resource " + identifier); if (item.Data == null) { setStatus("&cFailed to download " + name); return false; } if (next != null) setStatus(MakeNext(next)); else setStatus("&eCreating default.zip.."); data = (byte[])item.Data; return true; } return true; } const string lineFormat = "&eFetching {0}.. ({1}/{2})"; public string MakeNext(string next) { CurrentResource++; return String.Format(lineFormat, next, CurrentResource, ResourcesCount); } bool CheckMusicFiles(Action setStatus) { string[] files = ResourceList.MusicFiles; for (int i = 0; i < files.Length; i++) { string next = i < files.Length - 1 ? files[i + 1] : "dig_cloth1"; string name = files[i]; byte[] data = null; if (!Download(name, name, next, ref data, setStatus)) return false; if (data == null) continue; string path = Path.Combine(Program.AppDirectory, "audio"); path = Path.Combine(path, name + ".ogg"); File.WriteAllBytes(path, data); } return true; } public void CheckResourceExistence() { ResourceChecker checker = new ResourceChecker(); checker.CheckResourceExistence(); AllResourcesExist = checker.AllResourcesExist; DigSoundsExist = checker.DigSoundsExist; StepSoundsExist = checker.StepSoundsExist; DownloadSize = checker.DownloadSize; ResourcesCount = checker.ResourcesCount; musicExists = checker.musicExists; } public bool AllResourcesExist, DigSoundsExist, StepSoundsExist; public float DownloadSize; public int ResourcesCount, CurrentResource; bool[] musicExists = new bool[7]; } }