mirror of
https://github.com/Gabi-Zar/Silk-Fly-Launcher.git
synced 2026-04-17 05:26:04 +02:00
Add the possibility to activate and deactivate mods
This commit is contained in:
114
main.js
114
main.js
@@ -38,7 +38,7 @@ let onlineCachedModList;
|
|||||||
let onlineTotalModsCount;
|
let onlineTotalModsCount;
|
||||||
|
|
||||||
const bepinexFiles = [".doorstop_version", "changelog.txt", "doorstop_config.ini", "winhttp.dll"];
|
const bepinexFiles = [".doorstop_version", "changelog.txt", "doorstop_config.ini", "winhttp.dll"];
|
||||||
let bepinexVersion;
|
let bepinexVersion = bepinexStore.get("bepinex-version");
|
||||||
let bepinexBackupVersion;
|
let bepinexBackupVersion;
|
||||||
|
|
||||||
let mainWindow;
|
let mainWindow;
|
||||||
@@ -120,6 +120,7 @@ app.on("open-url", (event, url) => {
|
|||||||
ipcMain.handle("save-path", (event, path) => {
|
ipcMain.handle("save-path", (event, path) => {
|
||||||
saveSilksongPath(path);
|
saveSilksongPath(path);
|
||||||
});
|
});
|
||||||
|
|
||||||
function saveSilksongPath(path) {
|
function saveSilksongPath(path) {
|
||||||
store.set("silksong-path", path);
|
store.set("silksong-path", path);
|
||||||
}
|
}
|
||||||
@@ -208,6 +209,7 @@ async function saveModInfo(modId, suppr = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const modInfo = onlineCachedModList.find((mod) => mod.modId == modId);
|
const modInfo = onlineCachedModList.find((mod) => mod.modId == modId);
|
||||||
|
modInfo.activated = true;
|
||||||
installedModsStore.set(String(modId), modInfo);
|
installedModsStore.set(String(modId), modInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,9 +312,7 @@ async function installBepinex() {
|
|||||||
saveBepinexVersion(release.tag_name);
|
saveBepinexVersion(release.tag_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await fileExists(modSavePath)) {
|
checkInstalledMods();
|
||||||
await fs.cp(modSavePath, path.join(silksongPath, "BepInEx", "plugins"), { recursive: true });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ipcMain.handle("install-bepinex", async () => {
|
ipcMain.handle("install-bepinex", async () => {
|
||||||
@@ -440,12 +440,12 @@ ipcMain.handle("get-mods", async (event, type) => {
|
|||||||
if (!installedCachedModList) {
|
if (!installedCachedModList) {
|
||||||
await searchInstalledMods("");
|
await searchInstalledMods("");
|
||||||
}
|
}
|
||||||
return { modsInfo: installedCachedModList, installedTotalCount: installedTotalModsCount };
|
return { installedModsInfo: installedCachedModList, installedTotalCount: installedTotalModsCount };
|
||||||
} else if (type == "mods-online") {
|
} else if (type == "mods-online") {
|
||||||
if (!onlineCachedModList) {
|
if (!onlineCachedModList) {
|
||||||
await searchNexusMods("");
|
await searchNexusMods("");
|
||||||
}
|
}
|
||||||
return { mods: onlineCachedModList, onlineTotalCount: onlineTotalModsCount };
|
return { onlineModsInfo: onlineCachedModList, onlineTotalCount: onlineTotalModsCount };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -511,38 +511,6 @@ async function startDownload(modId, fileId, key, expires) {
|
|||||||
installedCachedModList = undefined;
|
installedCachedModList = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkInstalledMods() {
|
|
||||||
const bepinexFolderPath = path.join(loadSilksongPath(), "BepInEx");
|
|
||||||
|
|
||||||
for (const [key, modInfo] of Object.entries(installedModsStore.store)) {
|
|
||||||
modInfo.modId = String(modInfo.modId);
|
|
||||||
if (!(await fileExists(path.join(modSavePath, modInfo.modId)))) {
|
|
||||||
saveModInfo(key, true);
|
|
||||||
await fs.rm(path.join(bepinexFolderPath, "plugins", modInfo.modId), { recursive: true });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ipcMain.handle("uninstall-mod", async (event, modId) => {
|
|
||||||
modId = String(modId);
|
|
||||||
const BepinexPluginsPath = path.join(loadSilksongPath(), "BepInEx", "plugins");
|
|
||||||
const modPath = path.join(BepinexPluginsPath, modId);
|
|
||||||
if (await fileExists(path.join(modSavePath, modId))) {
|
|
||||||
await fs.rm(path.join(modSavePath, modId), { recursive: true });
|
|
||||||
}
|
|
||||||
if (await fileExists(modPath)) {
|
|
||||||
await fs.rm(modPath, { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < installedCachedModList.length; i++) {
|
|
||||||
if (installedCachedModList[i].modId == modId) {
|
|
||||||
installedCachedModList.splice(i, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
saveModInfo(modId, true);
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.handle("search-nexus-mods", async (event, keywords, offset, count, sortFilter, sortOrder) => {
|
ipcMain.handle("search-nexus-mods", async (event, keywords, offset, count, sortFilter, sortOrder) => {
|
||||||
await searchNexusMods(keywords, offset, count, sortFilter, sortOrder);
|
await searchNexusMods(keywords, offset, count, sortFilter, sortOrder);
|
||||||
});
|
});
|
||||||
@@ -608,6 +576,9 @@ async function searchNexusMods(keywords, offset = 0, count = 10, sortFilter = "d
|
|||||||
onlineTotalModsCount = data.mods.totalCount;
|
onlineTotalModsCount = data.mods.totalCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
//////////////////////// MODS ////////////////////////
|
||||||
|
|
||||||
ipcMain.handle("search-installed-mods", async (event, keywords, offset, count, sortFilter, sortOrder) => {
|
ipcMain.handle("search-installed-mods", async (event, keywords, offset, count, sortFilter, sortOrder) => {
|
||||||
await searchInstalledMods(keywords, offset, count, sortFilter, sortOrder);
|
await searchInstalledMods(keywords, offset, count, sortFilter, sortOrder);
|
||||||
});
|
});
|
||||||
@@ -635,6 +606,73 @@ async function searchInstalledMods(keywords, offset = 0, count = 10, sortFilter
|
|||||||
installedCachedModList = modsInfoSorted.slice(offset, offset + count);
|
installedCachedModList = modsInfoSorted.slice(offset, offset + count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function checkInstalledMods() {
|
||||||
|
const bepinexPluginsPath = path.join(loadSilksongPath(), "BepInEx", "plugins");
|
||||||
|
|
||||||
|
for (const [key, modInfo] of Object.entries(installedModsStore.store)) {
|
||||||
|
modInfo.modId = String(modInfo.modId);
|
||||||
|
if (!(await fileExists(path.join(modSavePath, modInfo.modId)))) {
|
||||||
|
saveModInfo(key, true);
|
||||||
|
if (await fileExists(path.join(bepinexPluginsPath, modInfo.modId))) {
|
||||||
|
await fs.rm(path.join(bepinexPluginsPath, modInfo.modId), { recursive: true });
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modInfo.activated) {
|
||||||
|
await fs.cp(path.join(modSavePath, modInfo.modId), path.join(bepinexPluginsPath, modInfo.modId), { recursive: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ipcMain.handle("uninstall-mod", async (event, modId) => {
|
||||||
|
modId = String(modId);
|
||||||
|
const BepinexPluginsPath = path.join(loadSilksongPath(), "BepInEx", "plugins");
|
||||||
|
const modPath = path.join(BepinexPluginsPath, modId);
|
||||||
|
if (await fileExists(path.join(modSavePath, modId))) {
|
||||||
|
await fs.rm(path.join(modSavePath, modId), { recursive: true });
|
||||||
|
}
|
||||||
|
if (await fileExists(modPath)) {
|
||||||
|
await fs.rm(modPath, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < installedCachedModList.length; i++) {
|
||||||
|
if (installedCachedModList[i].modId == modId) {
|
||||||
|
installedCachedModList.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
saveModInfo(modId, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle("activate-mod", async (event, modId) => {
|
||||||
|
const BepinexPluginsPath = path.join(loadSilksongPath(), "BepInEx", "plugins");
|
||||||
|
|
||||||
|
if (!installedModsStore.get(`${modId}.activated`)) {
|
||||||
|
installedModsStore.set(`${modId}.activated`, true);
|
||||||
|
|
||||||
|
if (bepinexVersion) {
|
||||||
|
if (!(await fileExists(path.join(BepinexPluginsPath, String(modId))))) {
|
||||||
|
await fs.cp(path.join(modSavePath, String(modId)), path.join(BepinexPluginsPath, String(modId)), { recursive: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle("deactivate-mod", async (event, modId) => {
|
||||||
|
const BepinexPluginsPath = path.join(loadSilksongPath(), "BepInEx", "plugins");
|
||||||
|
|
||||||
|
if (installedModsStore.get(`${modId}.activated`)) {
|
||||||
|
installedModsStore.set(`${modId}.activated`, false);
|
||||||
|
|
||||||
|
if (bepinexVersion) {
|
||||||
|
if (await fileExists(path.join(BepinexPluginsPath, String(modId)))) {
|
||||||
|
await fs.rm(path.join(BepinexPluginsPath, String(modId)), { recursive: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
//////////////////// UNCATEGORIZE ////////////////////
|
//////////////////// UNCATEGORIZE ////////////////////
|
||||||
|
|
||||||
|
|||||||
11
preload.js
11
preload.js
@@ -45,9 +45,14 @@ contextBridge.exposeInMainWorld("bepinex", {
|
|||||||
|
|
||||||
contextBridge.exposeInMainWorld("nexus", {
|
contextBridge.exposeInMainWorld("nexus", {
|
||||||
verifyAPI: () => ipcRenderer.invoke("verify-nexus-api"),
|
verifyAPI: () => ipcRenderer.invoke("verify-nexus-api"),
|
||||||
getMods: (type) => ipcRenderer.invoke("get-mods", type),
|
|
||||||
download: (link) => ipcRenderer.invoke("open-download", link),
|
download: (link) => ipcRenderer.invoke("open-download", link),
|
||||||
uninstall: (modId) => ipcRenderer.invoke("uninstall-mod", modId),
|
|
||||||
search: (keywords, offset, count, sortFilter, sortOrder) => ipcRenderer.invoke("search-nexus-mods", keywords, offset, count, sortFilter, sortOrder),
|
search: (keywords, offset, count, sortFilter, sortOrder) => ipcRenderer.invoke("search-nexus-mods", keywords, offset, count, sortFilter, sortOrder),
|
||||||
searchInstalled: (keywords, offset, count, sortFilter, sortOrder) => ipcRenderer.invoke("search-installed-mods", keywords, offset, count, sortFilter, sortOrder),
|
});
|
||||||
|
|
||||||
|
contextBridge.exposeInMainWorld("mods", {
|
||||||
|
searchInstalled: (keywords, offset, count, sortFilter, sortOrder) => ipcRenderer.invoke("search-installed-mods", keywords, offset, count, sortFilter, sortOrder),
|
||||||
|
uninstall: (modId) => ipcRenderer.invoke("uninstall-mod", modId),
|
||||||
|
getMods: (type) => ipcRenderer.invoke("get-mods", type),
|
||||||
|
activateMods: (modId) => ipcRenderer.invoke("activate-mod", modId),
|
||||||
|
deactivateMods: (modId) => ipcRenderer.invoke("deactivate-mod", modId),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -170,6 +170,11 @@
|
|||||||
<div class="horizontal-div">
|
<div class="horizontal-div">
|
||||||
<a href="www.nexusmods.com/hollowknightsilksong/mods" class="default-button" id="uninstall-mod-button">Uninstall</a>
|
<a href="www.nexusmods.com/hollowknightsilksong/mods" class="default-button" id="uninstall-mod-button">Uninstall</a>
|
||||||
<a href="www.nexusmods.com/hollowknightsilksong/mods" class="default-button" id="external-link">Website</a>
|
<a href="www.nexusmods.com/hollowknightsilksong/mods" class="default-button" id="external-link">Website</a>
|
||||||
|
<p>Activated:</p>
|
||||||
|
<label class="checkbox-container">
|
||||||
|
<input type="checkbox" name="activated-mod" id="activated-mod" />
|
||||||
|
<span class="checkmark"></span>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -221,7 +226,7 @@
|
|||||||
<li id="Steel" onclick="changeTheme('Steel')">Steel</li>
|
<li id="Steel" onclick="changeTheme('Steel')">Steel</li>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<label class="lace-pin-checkbox-container">
|
<label class="checkbox-container">
|
||||||
<input type="checkbox" name="lace-pin" id="lace-pin" />
|
<input type="checkbox" name="lace-pin" id="lace-pin" />
|
||||||
<span class="checkmark"></span>
|
<span class="checkmark"></span>
|
||||||
Lace Pin
|
Lace Pin
|
||||||
|
|||||||
@@ -98,14 +98,15 @@ async function navigate(page) {
|
|||||||
toggleSelectedListButton("sort-menu", installedSortFilter);
|
toggleSelectedListButton("sort-menu", installedSortFilter);
|
||||||
setSortOrderButton();
|
setSortOrderButton();
|
||||||
|
|
||||||
const { modsInfo, installedTotalCount } = await nexus.getMods(page);
|
const { installedModsInfo, installedTotalCount } = await mods.getMods(page);
|
||||||
installedModsTotalCount = installedTotalCount;
|
installedModsTotalCount = installedTotalCount;
|
||||||
if (modsInfo == []) {
|
if (installedModsInfo == []) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const modInfo of modsInfo) {
|
for (const modInfo of installedModsInfo) {
|
||||||
const installedModTemplateCopy = installedModTemplate.content.cloneNode(true);
|
const installedModTemplateCopy = installedModTemplate.content.cloneNode(true);
|
||||||
|
|
||||||
if (modInfo.name) {
|
if (modInfo.name) {
|
||||||
const modTitleText = installedModTemplateCopy.getElementById("mod-title");
|
const modTitleText = installedModTemplateCopy.getElementById("mod-title");
|
||||||
modTitleText.innerText = modInfo.name;
|
modTitleText.innerText = modInfo.name;
|
||||||
@@ -143,6 +144,21 @@ async function navigate(page) {
|
|||||||
modVersionText.innerText = `V${modInfo.version} last updated on ${modInfo.updatedAt.slice(0, 10)}`;
|
modVersionText.innerText = `V${modInfo.version} last updated on ${modInfo.updatedAt.slice(0, 10)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isActivatedCheckbox = installedModTemplateCopy.getElementById("activated-mod");
|
||||||
|
if (modInfo.activated) {
|
||||||
|
isActivatedCheckbox.checked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
isActivatedCheckbox.addEventListener("change", async function () {
|
||||||
|
if (this.checked) {
|
||||||
|
mods.activateMods(modInfo.modId);
|
||||||
|
searchInstalledMods();
|
||||||
|
} else {
|
||||||
|
mods.deactivateMods(modInfo.modId);
|
||||||
|
searchInstalledMods();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const modUrl = `https://www.nexusmods.com/hollowknightsilksong/mods/${modInfo.modId}`;
|
const modUrl = `https://www.nexusmods.com/hollowknightsilksong/mods/${modInfo.modId}`;
|
||||||
|
|
||||||
const modLinkButton = installedModTemplateCopy.getElementById("external-link");
|
const modLinkButton = installedModTemplateCopy.getElementById("external-link");
|
||||||
@@ -156,7 +172,7 @@ async function navigate(page) {
|
|||||||
const uninstallModButton = installedModTemplateCopy.getElementById("uninstall-mod-button");
|
const uninstallModButton = installedModTemplateCopy.getElementById("uninstall-mod-button");
|
||||||
uninstallModButton.addEventListener("click", async function (event) {
|
uninstallModButton.addEventListener("click", async function (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
await nexus.uninstall(modInfo.modId);
|
await mods.uninstall(modInfo.modId);
|
||||||
|
|
||||||
navigate("refresh");
|
navigate("refresh");
|
||||||
});
|
});
|
||||||
@@ -182,12 +198,12 @@ async function navigate(page) {
|
|||||||
toggleSelectedListButton("sort-menu", onlineSortFilter);
|
toggleSelectedListButton("sort-menu", onlineSortFilter);
|
||||||
setSortOrderButton();
|
setSortOrderButton();
|
||||||
|
|
||||||
const { mods, onlineTotalCount } = await nexus.getMods(page);
|
const { onlineModsInfo, onlineTotalCount } = await mods.getMods(page);
|
||||||
onlineModsTotalCount = onlineTotalCount;
|
onlineModsTotalCount = onlineTotalCount;
|
||||||
if (mods == undefined) {
|
if (onlineModsInfo == undefined) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (const mod of mods) {
|
for (const mod of onlineModsInfo) {
|
||||||
if (mod.name == undefined) {
|
if (mod.name == undefined) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -448,7 +464,7 @@ async function setBepinexVersion() {
|
|||||||
async function searchInstalledMods() {
|
async function searchInstalledMods() {
|
||||||
const searchInput = document.getElementById("search-input");
|
const searchInput = document.getElementById("search-input");
|
||||||
searchValueInstalled = searchInput.value;
|
searchValueInstalled = searchInput.value;
|
||||||
await nexus.searchInstalled(searchValueInstalled, installedOffset, installedModsCount, installedSortFilter, installedSortOrder);
|
await mods.searchInstalled(searchValueInstalled, installedOffset, installedModsCount, installedSortFilter, installedSortOrder);
|
||||||
await navigate("refresh");
|
await navigate("refresh");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ body {
|
|||||||
background: var(--primary-color);
|
background: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.lace-pin-checkbox-container {
|
.checkbox-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -356,13 +356,13 @@ body {
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lace-pin-checkbox-container input {
|
.checkbox-container input {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
width: 0;
|
width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lace-pin-checkbox-container .checkmark {
|
.checkbox-container .checkmark {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
@@ -373,27 +373,27 @@ body {
|
|||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lace-pin-checkbox-container:hover .checkmark {
|
.checkbox-container:hover .checkmark {
|
||||||
background: var(--darker-transparent-black);
|
background: var(--darker-transparent-black);
|
||||||
border-color: var(--primary-color);
|
border-color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.lace-pin-checkbox-container input:checked ~ .checkmark {
|
.checkbox-container input:checked ~ .checkmark {
|
||||||
background: var(--primary-color);
|
background: var(--primary-color);
|
||||||
border-color: var(--primary-color);
|
border-color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.lace-pin-checkbox-container .checkmark:after {
|
.checkbox-container .checkmark:after {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lace-pin-checkbox-container input:checked ~ .checkmark:after {
|
.checkbox-container input:checked ~ .checkmark:after {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lace-pin-checkbox-container .checkmark:after {
|
.checkbox-container .checkmark:after {
|
||||||
left: 8px;
|
left: 8px;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
|
|||||||
Reference in New Issue
Block a user