Commit f516a543 authored by Andreas Heimann's avatar Andreas Heimann

rudimentary backup loading and copying

parent b36d993f
const { app, BrowserWindow } = require('electron');
function createWindow () {
const win = new BrowserWindow({
width: 1300,
height: 700,
minHeight: 590,
minWidth: 840,
webPreferences: {
nodeIntegration: true
}
});
win.loadFile('./src/app.htm');
win.webContents.openDevTools();
win.setMenuBarVisibility(false);
}
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
\ No newline at end of file
This diff is collapsed.
{
"name": "customspeens-client",
"version": "0.1.0",
"main": "main.js",
"description": "Spin Rhythm XD Custom Songs",
"scripts": {
"start": "electron ."
},
"author": "Andreas Heimann",
"license": "MIT",
"devDependencies": {
"electron": "^8.0.1"
},
"dependencies": {
"ncp": "^2.0.0",
"rimraf": "^3.0.2",
"unzipper": "^0.10.10"
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Spin Rhythm XD Custom Songs</title>
<!-- Meta Tags -->
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
<!-- Styles -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&display=swap" />
<link rel="stylesheet" href="https://cdn.materialdesignicons.com/5.0.45/css/materialdesignicons.min.css" />
<link rel="stylesheet" href="assets/css/main.css" />
</head>
<body>
<header>
<div class="title">CustomSpeens</div>
</header>
<section class="section-startup active">
<button class="open-backup-button" onclick="UIOpenBackup()">Open Backup</button>
</section>
<section class="section-trackinfo">
<div class="cover ui-song-cover"></div>
<div class="metadata">
<div class="ui-song-title">Title is here!</div>
<div class="ui-song-subtitle">Subtitle is here!</div>
<div class="ui-song-artist">Song by Artist</div>
<div class="ui-song-author">Chart by Author</div>
</div>
<div class="actions">
<button class="copy-backup-button" onclick="UICopyBackup()">Copy to Game</button>
</div>
</section>
<section class="section-result"></section>
<!-- Scripts -->
<script src="./assets/js/app.js"></script>
</body>
</html>
\ No newline at end of file
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
html {
width: 100%;
height: 100%;
}
body {
width: 100%;
height: 100%;
margin: 0;
background: #212629;
color: #fff;
overflow: hidden;
font-family: 'Open Sans', sans-serif;
font-size: 14px;
}
.tooltip {
background: #000;
color: #fff;
padding: 5px 15px;
border-radius: 4px;
position: absolute;
z-index: 100;
font-size: 12px;
font-weight: bold;
text-transform: uppercase;
display: none;
}
.tooltip.active {
display: block;
}
button,
.button {
font-family: 'Open Sans', sans-serif;
font-size: 12px;
color: #fff;
background: rgba(255, 255, 255, 0.2);
text-transform: uppercase;
font-weight: 700;
border-radius: 4px;
padding: 7px 14px;
border: 0px;
transition: 0.2s ease-in-out all;
}
button:hover,
.button:hover {
background: #fff;
color: #222;
cursor: pointer;
}
button:focus,
.button:focus {
outline: 0;
}
header {
background: rgba(255, 255, 255, 0.1);
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.4);
}
header .title {
font-size: 20px;
padding: 15px 40px;
}
section {
margin: 20px;
padding: 20px;
background: rgba(255, 255, 255, 0.1);
border-radius: 5px;
display: none;
}
section.active {
display: block;
}
section.section-trackinfo {
grid-template-columns: 100px auto;
grid-template-rows: auto auto;
grid-template-areas: "cover metadata" "actions actions";
grid-gap: 25px;
}
section.section-trackinfo.active {
display: grid;
}
section.section-trackinfo .cover {
width: 100px;
height: 100px;
background: rgba(255, 255, 255, 0.2);
border-radius: 4px;
grid-area: cover;
background-size: cover;
}
section.section-trackinfo .metadata {
grid-area: metadata;
}
section.section-trackinfo .metadata .ui-song-title {
font-size: 1.25em;
font-weight: bold;
}
section.section-trackinfo .metadata .ui-song-subtitle {
margin-bottom: 15px;
}
section.section-trackinfo .metadata .ui-song-artist {
margin-bottom: 5px;
opacity: 0.6;
}
section.section-trackinfo .metadata .ui-song-author {
opacity: 0.6;
}
section.section-trackinfo .actions {
grid-area: actions;
}
section.section-result {
padding: 20px;
text-align: center;
}
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
html {
width: 100%;
height: 100%;
}
body {
width: 100%;
height: 100%;
margin: 0;
background: #212629;
color: #fff;
overflow: hidden;
font-family: 'Open Sans', sans-serif;
font-size: 14px;
}
.tooltip {
background: #000;
color: #fff;
padding: 5px 15px;
border-radius: 4px;
position: absolute;
z-index: 100;
font-size: 12px;
font-weight: bold;
text-transform: uppercase;
display: none;
&.active {
display: block;
}
}
button, .button {
font-family: 'Open Sans', sans-serif;
font-size: 12px;
color: #fff;
background: rgba(255,255,255,0.2);
text-transform: uppercase;
font-weight: 700;
border-radius: 4px;
padding: 7px 14px;
border: 0px;
transition: 0.2s ease-in-out all;
&:hover {
background: #fff;
color: #222;
cursor: pointer;
}
&:focus {
outline: 0;
}
}
header {
background: rgba(255,255,255,0.1);
box-shadow: 0px 4px 8px rgba(0,0,0,0.4);
& .title {
font-size: 20px;
padding: 15px 40px;
}
}
section {
margin: 20px;
padding: 20px;
background: rgba(255,255,255,0.1);
border-radius: 5px;
display: none;
&.active {
display: block;
}
&.section-trackinfo {
grid-template-columns: 100px auto;
grid-template-rows: auto auto;
grid-template-areas: "cover metadata"
"actions actions";
grid-gap: 25px;
&.active { display: grid; }
& .cover {
width: 100px;
height: 100px;
background: rgba(255,255,255,0.2);
border-radius: 4px;
grid-area: cover;
background-size: cover;
}
& .metadata {
grid-area: metadata;
& .ui-song-title {
font-size: 1.25em;
font-weight: bold;
}
& .ui-song-subtitle {
margin-bottom: 15px;
}
& .ui-song-artist {
margin-bottom: 5px;
opacity: 0.6;
}
& .ui-song-author {
opacity: 0.6;
}
}
& .actions {
grid-area: actions;
}
}
&.section-result {
padding: 20px;
text-align: center;
}
}
\ No newline at end of file
const { dialog, shell, app } = require('electron').remote;
let fs = require('fs');
let path = require('path');
let rimraf = require('rimraf');
let ncp = require('ncp');
let unzipper = require('unzipper');
// System References
let systemOS = "";
let tempDirLocation = "";
let gameDirLocation = "";
// Backup Data
let currentBackupLocation = "";
let currentSRTBLocation = "";
let currentSongLocation = "";
let currentSongTrackInfo = {};
// UI Referrences
let DOMSectionStartup = document.querySelector(".section-startup");
let DOMSectionTrackinfo = document.querySelector(".section-trackinfo");
let DOMSectionResult = document.querySelector(".section-result");
let DOMUISongCover = document.querySelector(".ui-song-cover");
let DOMUISongTitle = document.querySelector(".ui-song-title");
let DOMUISongSubtitle = document.querySelector(".ui-song-subtitle");
let DOMUISongArtist = document.querySelector(".ui-song-artist");
let DOMUISongAuthor = document.querySelector(".ui-song-author");
// Init System References
Init();
function Init() {
console.log("Initializing System.");
systemOS = process.platform;
tempDirLocation = app.getPath('temp');
// TODO: Mac/Linux Support
if(process.platform == "win32") {
gameDirLocation = path.join(app.getPath("userData"), "../..", "LocalLow", "Super Spin Digital", "Spin Rhythm XD", "Custom");
}
}
function UIOpenBackup() {
dialog.showOpenDialog({ title: "Open Backup", properties: ['openFile'], filters: [{"name": "Backup Archive", "extensions": ["zip"]}] }).then(result => {
if(!result.canceled) {
let filePath = result.filePaths[0];
let fileName = path.basename(filePath);
loadBackup(filePath, fileName).then(function(result) {
if(result) {
UIUpdateMetadata();
} else {
console.error("Backup could not be loaded!");
}
});
}
});
}
function UICopyBackup() {
copyBackup();
}
function UIUpdateMetadata() {
console.log(currentSongTrackInfo);
DOMSectionTrackinfo.classList.add("active");
DOMUISongCover.style.backgroundImage = "url(" + getSongCover(currentSongTrackInfo.albumArtReference.assetName) + ")";
DOMUISongTitle.innerHTML = currentSongTrackInfo.title;
DOMUISongSubtitle.innerHTML = currentSongTrackInfo.subtitle;
DOMUISongArtist.innerHTML = "Song by " + currentSongTrackInfo.artistName;
DOMUISongAuthor.innerHTML = "Chart by " + currentSongTrackInfo.charter;
}
async function loadBackup(filePath, fileName) {
if(currentBackupLocation != "") {
console.log("Unload previous Backup.");
unloadBackup();
}
console.log("Extracting Backup.");
currentBackupLocation = path.join(tempDirLocation, fileName);
console.info(currentBackupLocation);
// Unzip to temp/CustomSpeens/Song
await fs.createReadStream(filePath).pipe(unzipper.Extract({ path: currentBackupLocation })).promise();
console.log("Loading Backup.");
// Find SRTB & OGG files
let srtbFilesInBackupLocation = getFilesFromPath(currentBackupLocation, ".srtb");
if(srtbFilesInBackupLocation.length < 1) {
console.error("No SRTB file found in backup.");
return false;
}
// Load SRTB file
currentSRTBLocation = path.join(currentBackupLocation, srtbFilesInBackupLocation[0]);
let srtbFile = JSON.parse( fs.readFileSync(currentSRTBLocation) );
currentSongTrackInfo = JSON.parse( srtbFile.largeStringValuesContainer.values[0].val );
// Load OGG file
let oggFilesInBackupLocation = getFilesFromPath(path.join(currentBackupLocation, "AudioClips"), ".ogg");
currentSongLocation = path.join(currentBackupLocation, oggFilesInBackupLocation[0]);
// TODO: Backup Validation
return true;
}
function copyBackup() {
// Copy temp folder to game dir
ncp(currentBackupLocation, gameDirLocation, function(error) {
DOMSectionResult.classList.add("active");
if(error) {
console.error(error);
DOMSectionResult.innerHTML = error;
return false;
}
DOMSectionResult.innerHTML = "Copied Backup Successfully!";
return true;
})
}
function unloadBackup() {
// Remove temp files
rimraf(currentBackupLocation, function() { console.log("Removed backup folder."); });
// Reset vars
currentBackupLocation = "";
currentSRTBLocation = "";
currentSongLocation = "";
currentSongTrackInfo = {};
}
// Used to find files by file extension
// by https://stackoverflow.com/a/52024318
function getFilesFromPath(path, extension) {
let dir = fs.readdirSync( path );
return dir.filter( elm => elm.match(new RegExp(`.*\.(${extension})$`, 'ig')));
}
function getSongCover(extension) {
let dir = fs.readdirSync( path.join(currentBackupLocation, "AlbumArt") );
let fileExtension = dir.filter( elm => elm.match(new RegExp(`(${extension}).*\.$`, 'ig')));
let finalPath = path.join(currentBackupLocation, "AlbumArt", fileExtension[0]);
let base64Data = "data:image/jpg;base64," + fs.readFileSync(finalPath, { encoding: 'base64' });
return base64Data;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment