private static JSONArray Cache_Git_Repo(string repo_url) { //EXAMPLE: https://api.github.com/repos/dsisco11/SR_Plugin_Loader/git/trees/master?recursive=1 string url = String.Format("{0}/git/trees/master?recursive=1", repo_url.TrimEnd(new char[] { '\\', '/' })); string jsonStr = null; if (!remote_file_cache.ContainsKey(url)) { // Fetch repo information //jsonStr = webClient.DownloadString(url); jsonStr = GetString(url); if (jsonStr == null || jsonStr.Length <= 0) { return(null); } remote_file_cache.Add(url, ENCODING.GetBytes(jsonStr)); SLog.Debug("Cached repository: {0}", url); } else { jsonStr = ENCODING.GetString(remote_file_cache[url]); } // Parse the json response from GitHub var git = SimpleJSON.JSON.Parse(jsonStr); var tree = git["tree"].AsArray; return(tree); }
public static void Plugin_Status_Change(Plugin p, bool enabled) { if (IN_LOADING_PHASE) { return; } SLog.Debug("Plugin_Status_Change: Saving config..."); Loader.Save_Config(); }
private static void Reset_Tracker_For_Repo(string repo_url) { string rSHA = Get_Repo_SHA(repo_url); JSONClass nr = new JSONClass(); nr["sha"] = rSHA; Tracker[repo_url] = nr; SLog.Debug("Reset tracker for repo. SHA: {0} | URL: {1}", rSHA, repo_url); Tracker.Save(); }
private uiTab Create_Spawn_Category_Menu(uiTabPanel container, SpawnCategory cty, HashSet <Identifiable.Id> ITEMS) { // This list will just have a bunch of pictures of slimes that can be spawned string catStr = Enum.GetName(typeof(SpawnCategory), cty); float ICON_SIZE = 100f; uiTab tab = container.Add_Tab(catStr); uiListView list = uiControl.Create <uiListView>(catStr, tab); list.Layout = new Layout_IconList(ICON_SIZE); list.Autosize_Method = AutosizeMethod.FILL; list.Autosize = true; foreach (Identifiable.Id ID in ITEMS) { Sprite sprite = null; try { sprite = Directors.lookupDirector.GetIcon(ID); } catch (KeyNotFoundException) { continue; } catch (Exception ex) { SLog.Debug(ex); } if (sprite == null) { continue; // Exclude anything without an icon out of respect for the devs, we will just assume things without an icon aren't in the game just yet I suppose... } var itm = uiControl.Create <uiListIcon>(list); if (sprite != null) { itm.Icon = sprite.texture; } else { itm.Icon = TextureHelper.icon_unknown; } itm.Title = Language.Translate(ID); itm.Set_Size(ICON_SIZE, ICON_SIZE); itm.onClicked += (uiControl c) => { Dev_Spawn_Item(ID); }; itm.Selectable = false; } return(tab); }
private static Sisco_Return onLevelLoaded(ref object sender, ref object[] args, ref object return_value) { // Each time we load the main menu we want to clear any and all upgrade related data to ensure nothing freaky happens when the player loads a new file. int lvl = (int)args[0]; if (lvl == 0 || Levels.isSpecial()) { System.Threading.Timer timer = null; timer = new System.Threading.Timer((object o) => { SLog.Debug("[Upgrades] Flushing custom upgrades..."); Upgrades.setup = false; Upgrades.Setup(); timer.Dispose(); }, null, 0, System.Threading.Timeout.Infinite); } return(null); }
internal static void Register(IUpgrade upgrade) { if (!ALL.ContainsKey(upgrade.Type)) { ALL.Add(upgrade.Type, new Dictionary <string, IUpgrade>()); } var dict = ALL[upgrade.Type]; if (dict.ContainsKey(upgrade.ID)) { SLog.Warn("[Upgrades] Blocked Attempt to register duplicate {0} upgrade instance for \"{1}\"", upgrade.Type, upgrade.ID); return; } //var old = ALL[upgrade.Type].FirstOrDefault(o => String.Compare(o.ID, upgrade.ID) == 0); //if (old != null) ALL[upgrade.Type].Remove(old); SLog.Debug("[Upgrades] Registered: {0}", upgrade.ID); ALL[upgrade.Type].Add(upgrade.ID, upgrade); }
/// <summary> /// /// </summary> /// <param name="url"></param> /// <returns>FileStream for the requested file.</returns> public IEnumerator Cache_And_Open_File_Async(string url) { string repo_url = Extract_Repository_URL_From_Github_URL(url); var iter = Cache_Git_Repo_Async(repo_url); while (iter.MoveNext()) { yield return(null); } JSONArray repo = iter.Current as JSONArray; string local_file = String.Format("{0}\\{1}", UnityEngine.Application.dataPath, Path.GetFileName(url)); var iter1 = Get_Update_Status_Async(url, local_file); while (iter1.MoveNext()) { yield return(null); } var update_status = (FILE_UPDATE_STATUS)iter1.Current; if (update_status == FILE_UPDATE_STATUS.OUT_OF_DATE) { SLog.Debug("Git_Updater.Cache_And_Open_File(): Downloading: {0} | File: {1}", url, Path.GetFileName(local_file)); var it = DownloadAsync(url, local_file); while (it.MoveNext()) { yield return(null); } } yield return(File.OpenRead(local_file)); yield break; }
private static Sisco_Return onGameSaved(ref object sender, ref object[] args, ref object return_value) { string gameName = (string)args[0]; string plyUpgradesFile = String.Concat(gameName, ".pug"); string plotUpgradesFile = String.Concat(gameName, ".plu"); SLog.Debug("Writing: {0}", plyUpgradesFile); SLog.Debug("Writing: {0}", plotUpgradesFile); // SAVE PLAYER UPGRADES // Always write to a temp file first when saving data string tmpFile = String.Concat(plyUpgradesFile, ".tmp"); List <string> upgrades_list = new List <string>(Player_Upgrades_Missing); upgrades_list.AddRange(PlayerUpgrades.Select(o => o.ID).ToArray()); File.WriteAllText(tmpFile, String.Join("\n", upgrades_list.Distinct(StringComparer.OrdinalIgnoreCase).ToArray())); File.Copy(tmpFile, plyUpgradesFile, true); File.Delete(tmpFile); // SAVE PLOT UPGRADES Save_Plot_Upgrades(plotUpgradesFile); return(null); }
public static void init(string hash) { lock (locker) { if (Loader.Config != null) { return; } //Application.stackTraceLogType = StackTraceLogType.Full; Logging.Logger.Begin(Path.Combine(Application.dataPath, "plugins.log")); Stopwatch timer = new Stopwatch(); timer.Start(); if (!Loader.Load_Config_Stream()) { return; } try { DebugHud.Init(); TextureHelper.Setup(); MaterialHelper.Setup(); SiscosHooks.Setup(); PluginLoader_Watermark.Setup(); MainMenu.Setup(); DebugUI.Setup(); Setup_Update_Helper(); bool ok = Verify_PluginLoader_Hash(hash); if (!ok) { return; } IN_LOADING_PHASE = true; Setup_Plugin_Dir(); Check_For_Updates(); Setup_Assembly_Resolver(); Upgrades.Setup(); Assemble_Plugin_List(); Load_Config(); IN_LOADING_PHASE = false; ResourceExt.map_SR_Icons(); plugin_updater = uiControl.Create <Plugin_Update_Viewer>();// This control manages itself and is only able to become visible under certain conditions which it will control. Therefore it needs no var to track it. plugin_updater.Show(); dev_tools = uiControl.Create <DevMenu>(); //dev_tools.Show(); //dev_tools.onShown += (uiWindow w) => { GameTime.Pause(); }; //dev_tools.onHidden += (uiWindow w) => { GameTime.Unpause(); }; //Misc_Experiments.Find_Common_Classes_For_Idents(new HashSet<Identifiable.Id> { Identifiable.Id.PINK_RAD_LARGO }); } catch (Exception ex) { SLog.Error("Exception during PluginLoader initialization!"); SLog.Error(ex); } finally { timer.Stop(); SLog.Debug("Plugin Loader initialized! Took: {0}ms", timer.ElapsedMilliseconds); } } }
public override FILE_UPDATE_STATUS Get_Update_Status(string remote_path, string local_file) { if (!File.Exists(local_file)) { return(FILE_UPDATE_STATUS.OUT_OF_DATE); } string repo_url = Extract_Repository_URL_From_Github_URL(remote_path); string remote_file = Extract_File_Path_From_Github_URL(remote_path); // Time to check with GitHub and see if there is a newer version of the plugin loader out! try { JSONArray repo = Cache_Git_Repo(repo_url); // Go ahead and get the hash for the file we're checking on. string cSHA = Util.Git_File_Sha1_Hash(local_file); // Let's make sure we didn't already check on this same file in the past. FILE_UPDATE_STATUS?lastResult = Get_Cached_Result(remote_path, local_file); //if we DID cache the result from a past check against this file then return it here and don't waste time. if (lastResult.HasValue) { SLog.Debug("Returning Cached Result: {2} | \"{0}\" | SHA({1})", local_file, cSHA, Enum.GetName(typeof(FILE_UPDATE_STATUS), lastResult.Value)); return(lastResult.Value); } if (repo == null) { SLog.Info("[AutoUpdater] Unable to cache git repository!"); return(FILE_UPDATE_STATUS.ERROR); } // Find the plugin loaders DLL installation file foreach (JSONNode file in repo) { if (String.Compare(file["path"], remote_file) == 0) { // Compare the SHA1 hash for the dll on GitHub to the hash for the one currently installed string nSHA = file["sha"]; //PLog.Info("nSHA({0}) cSHA({1}) local_file: {2}", nSHA, cSHA, local_file); if (String.Compare(nSHA, cSHA) != 0) { // ok they don't match, now let's just make double sure that it isn't because we are using an unreleased developer version // First find the url for the file on GitHub string tmpurl = file["url"]; // now we want to replace it's hash with ours and check if it exists! tmpurl = tmpurl.Replace(nSHA, cSHA); // Check if the file for the currently installed loaders sha1 hash exists. bool exist = false; try { exist = Query_Remote_File_Exists(tmpurl); //PLog.Info("Query_Remote_File_Exists: {0} = {1}", tmpurl, (exist ? "TRUE" : "FALSE")); } catch (WebException wex) { if (wex.Status == WebExceptionStatus.ProtocolError) { var response = wex.Response as HttpWebResponse; if (response != null) { if (response.StatusCode == HttpStatusCode.NotFound)// A file for this hash does not exhist on the github repo. So this must be a Dev version. { exist = false; } } } } if (!exist) { //PLog.Info("[Updater] Dev file: {0}", Path.GetFileName(local_file)); Cache_Result(remote_path, local_file, FILE_UPDATE_STATUS.DEV_FILE); return(FILE_UPDATE_STATUS.DEV_FILE); } //PLog.Info("[Updater] Outdated file: {0}", Path.GetFileName(local_file)); Cache_Result(remote_path, local_file, FILE_UPDATE_STATUS.OUT_OF_DATE); return(FILE_UPDATE_STATUS.OUT_OF_DATE); } else { Cache_Result(remote_path, local_file, FILE_UPDATE_STATUS.UP_TO_DATE); return(FILE_UPDATE_STATUS.UP_TO_DATE); } } } } catch (WebException wex) { SLog.Error(wex); } catch (Exception ex) { SLog.Error(ex); } SLog.Debug("[Git_Updater] Unable to find file in repository: {0}", remote_file); return(FILE_UPDATE_STATUS.NOT_FOUND);//no update }
/// <summary> /// /// </summary> /// <param name="repo_url"></param> /// <returns>JSONArray holding all of the repository master branch entries</returns> private static IEnumerator Cache_Git_Repo_Async(string repo_url) { //EXAMPLE: https://api.github.com/repos/dsisco11/SR_Plugin_Loader/git/trees/master?recursive=1 string ghurl = Extract_Repository_URL_From_Github_URL(repo_url.TrimEnd(new char[] { '\\', '/' })); string url = String.Format("{0}/git/trees/master?recursive=1", ghurl); byte[] buf = null; string jsonStr = null; if (!remote_file_cache.ContainsKey(url)) { // Fetch repo information //jsonStr = webClient.DownloadString(url); IEnumerator iter = GetAsync(url); while (iter.MoveNext()) { yield return(null); } if (iter.Current == null) { yield return(null); yield break; } buf = iter.Current as byte[]; if (buf == null || buf.Length <= 0) { yield return(null); yield break; } jsonStr = ENCODING.GetString(buf); if (jsonStr == null || jsonStr.Length <= 0) { yield return(null); yield break; } //Check again just to make sure, because async methods could screw us up here. if (!remote_file_cache.ContainsKey(url)) { remote_file_cache.Add(url, ENCODING.GetBytes(jsonStr)); } remote_file_cache[url] = ENCODING.GetBytes(jsonStr); SLog.Debug("Cached repository: {0}", repo_url); } else { jsonStr = ENCODING.GetString(remote_file_cache[url]); //PLog.Info("CACHE: {0}", jsonStr); //DebugHud.Log(remote_file_cache.ToLogString()); } // Parse the json response from GitHub var git = SimpleJSON.JSON.Parse(jsonStr); var tree = git["tree"].AsArray; yield return(tree); yield break; }
// Remember: when this function is used by plugins they will pass their given updater_method URL for 'remote_file' // In the case of things like the Git updater this is fine as that url will BE a link to the most current version of the plugin DLL // However in the case of the JSON updater that url will instead be a link to the JSON file containing the HASH and DOWNLOAD URL for said plugin. // So for the JSON updater this method needs to be overriden and made to download that JSON info and treat the DOWNLOAD url contained therein as if IT was passed as the 'remote_file' public virtual IEnumerator DownloadAsync(string remote_file, string local_file, Updater_File_Type_Confirm confirm = null, Updater_File_Download_Progress prog_callback = null, Updater_File_Download_Completed download_completed = null) { SLog.Debug("Downloading: {0}", remote_file); if (local_file == null) { local_file = String.Format("{0}\\{1}", UnityEngine.Application.dataPath, Path.GetFileName(remote_file)); } WebResponse resp = null; Stream stream = null; HttpWebRequest webRequest = CreateRequest(remote_file); WebAsync webAsync = new WebAsync(); IEnumerator e = webAsync.GetResponse(webRequest); while (e.MoveNext()) { yield return(e.Current); } // wait for response to arrive while (!webAsync.isResponseCompleted) { yield return(null); // double check for clarity & safety } RequestState result = webAsync.requestState; resp = result.webResponse; if (confirm != null) { if (confirm(resp.ContentType) == false) { yield break;//exit routine } } stream = resp.GetResponseStream(); int total = (int)resp.ContentLength; byte[] buf = new byte[total]; int read = 0; //how many bytes we have read so far (offset within the stream) int remain = total; //how many bytes are left to read int r = 0; while (remain > 0) { r = stream.Read(buf, read, Math.Min(remain, CHUNK_SIZE)); read += r; remain -= r; if (prog_callback != null) { try { prog_callback(read, total); } catch (Exception ex) { SLog.Error(ex); } } yield return(0);// yield execution until next frame } // It's good practice when overwriting files to write the new version to a temporary location and then copy it overtop of the original. string temp_file = String.Format("{0}.temp", local_file); File.WriteAllBytes(temp_file, buf); File.Copy(temp_file, local_file, true); File.Delete(temp_file);// delete the now unneeded .temp file download_completed?.Invoke(local_file); yield break;//exit routine }