private static void SetNonFrogtownModStatus(ModDetails details, bool enable) { string src, dst; var display = details.dllFileName.Substring(1, details.dllFileName.Length - 1); if (enable) { src = DISABLED_MOD_FOLDER + "\\" + details.dllFileName; dst = ENABLED_MOD_FOLDER + "\\" + details.dllFileName; FrogtownShared.Log("FrogShared", LogLevel.Info, display + " moved to plugins, will be loaded after restart."); } else { src = details.dllFileFullPath; if (string.IsNullOrEmpty(src)) { src = ENABLED_MOD_FOLDER + "\\" + details.dllFileName; } dst = DISABLED_MOD_FOLDER + "\\" + details.dllFileName; FrogtownShared.Log("FrogShared", LogLevel.Info, display + " moved to disabled, will be unloaded after restart."); } System.IO.File.Move(src, dst); details.enabled = enable; //Don't call afterToggle because they aren't actually changed until restart }
private static void AfterModToggle(ModDetails details) { if (details.frogtownModDetails != null && details.frogtownModDetails.isNotCheaty) { return; } if (whitelistFrameworkUnlisted.Contains(details.GUID)) { return; } if (details.enabled) { modCount++; FrogtownShared.Log("FrogShared", LogLevel.Info, details.GUID + " enabled."); } else { modCount--; FrogtownShared.Log("FrogShared", LogLevel.Info, details.GUID + " disabled."); } bool newIsModded = modCount > 0; if (RoR2Application.isModded != newIsModded) { RoR2Application.isModded = newIsModded; FrogtownShared.Log("FrogShared", LogLevel.Info, "Set isModded flag to " + newIsModded); } }
private void WindowFunction(int windowId) { if (Input.GetKey(KeyCode.LeftControl)) { GUI.DragWindow(windowRect); } UnityAction buttons = () => { }; GUILayout.BeginVertical("box"); GUILayout.Label("Frogtown Mod Manager 2.0.3", h1); GUILayout.BeginVertical("box"); GUILayout.Space(3); int tab = tabId; tab = GUILayout.Toolbar(tab, tabs, button, GUILayout.ExpandWidth(false)); if (tab != tabId) { tabId = tab; } GUILayout.Space(5); if (tabId == 0) { DrawModTab(ref buttons); } if (tabId == 1) { DrawSettingsTab(ref buttons); } if (tabId == 2) { DrawLogTab(ref buttons); } GUILayout.FlexibleSpace(); GUILayout.Space(5); GUILayout.BeginHorizontal(); if (GUILayout.Button(new GUIContent("Close", "Close the overlay."), button, GUILayout.ExpandWidth(false))) { ToggleWindow(); } if (GUILayout.Button(new GUIContent("Mod Folder", "Open the plugin folder where mod DLLs should be placed."), button, GUILayout.ExpandWidth(false))) { string url = "file://" + BepInEx.Paths.PluginPath; FrogtownShared.Log("FrogShared", LogLevel.Info, "Openning " + url); Application.OpenURL(url); } buttons(); GUILayout.Label(GUI.tooltip); GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUILayout.EndVertical(); }
public static void TriggerChatCommand(string userName, string[] pieces) { if (pieces.Length == 0) { return; } if (chatCommandList.TryGetValue(pieces[0].ToUpper(), out var list)) { foreach (var func in list) { try { func.Invoke(userName, pieces); } catch (Exception e) { FrogtownShared.Log("FrogShared", LogLevel.Error, "Command " + pieces[0] + " logged exception \"" + e.Message + "\""); FrogtownShared.Log("FrogShared", LogLevel.Error, e.StackTrace); } } } }
public void Log(LogLevel level, string message) { FrogtownShared.Log(GUID, level, message); }
private void DrawModTab(ref UnityAction buttons) { var minWidth = GUILayout.MinWidth(windowSize.x); scrollPositions[0] = GUILayout.BeginScrollView(scrollPositions[0], minWidth, GUILayout.ExpandHeight(false)); var amountWidth = columns.Where(x => !x.skip).Sum(x => x.width); var expandWidth = columns.Where(x => x.expand && !x.skip).Sum(x => x.width); var colWidth = columns.Select(x => x.expand ? GUILayout.Width(x.width / expandWidth * (windowSize.x - 60 + expandWidth - amountWidth)) : GUILayout.Width(x.width)).ToArray(); GUILayout.BeginVertical(); GUILayout.BeginHorizontal("box"); for (int i = 0; i < columns.Count; i++) { if (columns[i].skip) { continue; } GUILayout.Label(columns[i].name, colWidth[i]); } GUILayout.EndHorizontal(); var GUIDs = ModManager.modDetails.Keys.ToArray(); Array.Sort(GUIDs, (a, b) => { ModManager.modDetails.TryGetValue(a, out ModDetails details); string aAuthor = details.frogtownModDetails?.githubAuthor ?? "Unknown"; ModManager.modDetails.TryGetValue(b, out details); string bAuthor = details.frogtownModDetails?.githubAuthor ?? "Unknown"; return(aAuthor.CompareTo(bAuthor)); }); List <ModRow> rows = new List <ModRow>(); string lastAuthor = ""; ModRow authorRow = null; foreach (string GUID in GUIDs) { ModManager.modDetails.TryGetValue(GUID, out ModDetails details); if (ModManager.whitelistFrameworkUnlisted.Contains(details.GUID)) { continue; } string author = details.frogtownModDetails?.githubAuthor ?? "Unknown"; if (author != lastAuthor) { if (authorRow != null) { rows.Add(authorRow); authorRow = null; } if (collapsedAuthors.Contains(author)) { authorRow = new ModRow(); ModRow rowAnchor = authorRow; authorRow.canToggle = ModManager.CanToggleMod(GUID, out bool isActive); if (authorRow.canToggle) { authorRow.isActive = isActive; } authorRow.githubAuthor = author; if (authorRow.githubAuthor != "Unknown") { authorRow.url = "https://github.com/" + author; authorRow.modName = "All mods from " + author; } else { authorRow.modName = "All mods from unknown authors"; } authorRow.isAuthorCollapsed = true; authorRow.description = details.modName; authorRow.firstForAuthor = true; if (details.frogtownModDetails == null && details.enabled != details.initialEnabled) { authorRow.statusStyle = red; authorRow.statusMessage = "Mod will be " + (details.enabled ? "enabled" : "disabled") + " the next time the game is started."; } authorRow.onToggleActive += () => { FrogtownShared.Log("FrogShared", LogLevel.Info, "Setting mods from " + rowAnchor.githubAuthor + " to " + !rowAnchor.isActive); foreach (string otherGUID in GUIDs) { ModManager.modDetails.TryGetValue(otherGUID, out ModDetails otherDetails); string otherAuthor = otherDetails.frogtownModDetails?.githubAuthor ?? "Unknown"; if (otherAuthor == author) { if (ModManager.CanToggleMod(otherGUID, out bool unused)) { ModManager.ToggleMod(otherGUID, !rowAnchor.isActive); } } } }; authorRow.onToggleAuthor += () => { collapsedAuthors.Remove(rowAnchor.githubAuthor); }; lastAuthor = author; continue; } } if (authorRow != null) { bool canToggle = ModManager.CanToggleMod(GUID, out bool isActive); authorRow.canToggle = authorRow.canToggle || canToggle; if (canToggle) { authorRow.isActive = authorRow.isActive || isActive; } authorRow.description += ", " + details.modName; if (details.frogtownModDetails == null && details.enabled != details.initialEnabled) { authorRow.statusStyle = red; authorRow.statusMessage = "Mod will be " + (details.enabled ? "enabled" : "disabled") + " the next time the game is started."; } } else { ModRow row = new ModRow(); row.canToggle = ModManager.CanToggleMod(GUID, out bool isActive); row.isActive = isActive; row.githubAuthor = author; if (details.frogtownModDetails != null) { row.url = "https://github.com/" + details.frogtownModDetails.githubAuthor + "/" + details.frogtownModDetails.githubRepo; } row.isAuthorCollapsed = false; row.modName = details.modName; row.description = details.frogtownModDetails?.description ?? ""; row.firstForAuthor = author != lastAuthor; row.version = details.version; row.newVersionLoading = details.frogtownModDetails?.newVersionLoading ?? false; row.newVersion = details.frogtownModDetails?.newVersion ?? ""; row.onToggleActive += () => { ModManager.ToggleMod(GUID, !row.isActive); }; row.onToggleAuthor += () => { collapsedAuthors.Add(row.githubAuthor); }; if (details.frogtownModDetails == null && details.enabled != details.initialEnabled) { row.statusStyle = red; row.statusMessage = "Mod will be " + (details.enabled ? "enabled" : "disabled") + " the next time the game is started."; } rows.Add(row); } lastAuthor = author; } if (authorRow != null) { rows.Add(authorRow); } foreach (var row in rows) { int col = -1; GUILayout.BeginHorizontal("box"); GUILayout.BeginHorizontal(colWidth[++col]); if (row.firstForAuthor) { bool newIsCollapsed = row.isAuthorCollapsed; newIsCollapsed = GUILayout.Toggle(newIsCollapsed, new GUIContent("", "Collapse mods from " + row.githubAuthor + ".")); if (newIsCollapsed != row.isAuthorCollapsed) { row.onToggleAuthor?.Invoke(); } } else { GUILayout.Label(" ", GUILayout.Width(56f)); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(colWidth[++col]); GUILayout.Label(new GUIContent(row.githubAuthor, row.description)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(colWidth[++col]); GUILayout.Label(new GUIContent(row.modName, row.description)); GUILayout.FlexibleSpace(); if (!string.IsNullOrEmpty(row.url)) { if (GUILayout.Button(new GUIContent("www", row.url), button)) { Application.OpenURL(row.url); } } else { GUILayout.Label(new GUIContent("---", "No repository available.")); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(colWidth[++col]); GUILayout.Label(row.version, curVersion, GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(colWidth[++col]); if (row.githubAuthor != "Unknown" && !row.isAuthorCollapsed) { if (row.newVersionLoading) { GUILayout.Label(new GUIContent("...", "Checking latest release...")); } else { if (!string.IsNullOrEmpty(row.newVersion)) { if (GUILayout.Button(row.newVersion, h2)) { Application.OpenURL(row.url + "/releases"); } } else { GUILayout.Label(new GUIContent("---", "No new version found.")); } } } else { GUILayout.Label(new GUIContent("---", "Can't load releases for " + row.modName + ".")); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(colWidth[++col]); if (row.canToggle) { bool newIsActive = row.isActive; newIsActive = GUILayout.Toggle(row.isActive, new GUIContent("", (row.isActive ? "Disable" : "Enable") + " " + row.modName + ".")); if (newIsActive != row.isActive) { row.onToggleActive?.Invoke(); } } else { GUILayout.Label(new GUIContent("X", row.modName + " cannot be disabled."), nodisable); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(colWidth[++col]); if (!string.IsNullOrEmpty(row.statusMessage)) { GUILayout.Label(new GUIContent("R", row.statusMessage), row.statusStyle); } GUILayout.EndHorizontal(); GUILayout.EndHorizontal(); } GUILayout.EndVertical(); GUILayout.EndScrollView(); }
internal static IEnumerator CheckForUpdates() { var config = FrogtownShared.GetConfig(); foreach (string GUID in modDetails.Keys) { if (modDetails.TryGetValue(GUID, out ModDetails details)) { if (details.frogtownModDetails != null) { details.newVersionLoading = true; } } } bool anyError = false; foreach (string GUID in modDetails.Keys) { if (modDetails.TryGetValue(GUID, out ModDetails details)) { if (details.frogtownModDetails != null) { string lastUpdateInst = config.Wrap("modupdates", "lastcheck-" + GUID, "", "0").Value; if (long.TryParse(lastUpdateInst, out long updateInst)) { DateTime lastUpdate = new DateTime(updateInst); if (lastUpdate.AddDays(0.5) > DateTime.Now) { string newV = config.Wrap("modupdates", "newestversion-" + GUID, "", "0").Value; if (newV.CompareTo(details.version) > 0) { details.frogtownModDetails.newVersion = newV; } FrogtownShared.Log("FrogShared", LogLevel.Info, "Loaded new version of " + GUID + " from cache."); details.newVersionLoading = false; continue; } } if (anyError) { details.newVersionLoading = false; continue; } string url = "https://api.github.com/repos/" + details.frogtownModDetails.githubAuthor + "/" + details.frogtownModDetails.githubRepo + "/releases"; FrogtownShared.Log("FrogShared", LogLevel.Info, "Requesting " + url); var req = UnityWebRequest.Get(url).SendWebRequest(); while (!req.isDone) { yield return(new WaitForEndOfFrame()); } details.newVersionLoading = false; if (req.webRequest.isHttpError || req.webRequest.isNetworkError) { FrogtownShared.Log("FrogShared", LogLevel.Error, "Error loading releases from " + url); anyError = true; } else { try { string text = req.webRequest.downloadHandler.text; string topRelease = ""; int ix = 0; while ((ix = text.IndexOf("\"tag_name\": \"")) >= 0) { text = text.Substring(ix + "\"tag_name\": \"".Length, text.Length - ix - "\"tag_name\": \"".Length); string version = text.Substring(0, text.IndexOf("\"")); if (version.CompareTo(topRelease) > 0 && version.CompareTo(details.version) > 0) { topRelease = version; } } details.frogtownModDetails.newVersion = topRelease; } catch (Exception e) { FrogtownShared.Log("FrogShared", LogLevel.Info, "Error parsing JSON "); FrogtownShared.Log("FrogShared", LogLevel.Info, e.Message + " " + e.StackTrace); } config.Wrap("modupdates", "lastcheck-" + GUID, "", "0").Value = DateTime.Now.Ticks.ToString(); config.Wrap("modupdates", "newestversion-" + GUID, "", "0").Value = details.frogtownModDetails.newVersion; } } } } config.Save(); }