Monty10

Active Member
Jan 30, 2024
612
610
You have to understand: the dev doesn’t include malware in his game, but the people who share his game on this forum might. I’m not saying that they do necessarily or even frequently, but they might.

Normally, some forum moderators will check the game before updating the OP; last time, some malware escaped their attention, that’s all.
You still didn't answer me
is this update has virus or not?
 

JYWH23

New Member
Jan 19, 2022
12
17
I know this has been asked a thousand times before but hope is never lost, anyone could share their savefile, I messed with mine like an idiot and I don't want to click through the whole game again.
 

Groomtinger

Newbie
Aug 9, 2017
38
167
Unlock All Collector Cards
This is only visual, and doesn't change any actual data

Modify /resources/app/data//SCRIPTS.js

Find @ L37886
JavaScript:
"formulas": [
    $(function() {
        if ($dataFields.globalData.cgGallery[o.parent.data[0].index].unlocked) {
            o.image = o.parent.data[0].thumb.name;
            return o.imageFolder = o.parent.data[0].thumb.folderPath;
        }
    }), $(function() {
        if (!$dataFields.globalData.cgGallery[o.parent.data[0].index].unlocked) {
            return o.image = "UI/locked.png";
        }
    })
]
Replace with:

JavaScript:
"formulas": [
    $(function() {
        if (true) {//$dataFields.globalData.cgGallery[o.parent.data[0].index].unlocked
            o.image = o.parent.data[0].thumb.name;
            return o.imageFolder = o.parent.data[0].thumb.folderPath;
        }
    }), $(function() {
        if (false) {//!$dataFields.globalData.cgGallery[o.parent.data[0].index].unlocked
            return o.image = "UI/locked.png";
        }
    })
]
I'm trying to figure out how to do the scenes themselves, so we don't always need a full save, but either I'm done or that's somewhere deeper I haven't found yet. Will update when I find it.
 
  • Like
Reactions: himler

himler

Member
Jun 16, 2017
118
105
Unlock All Collector Cards
This is only visual, and doesn't change any actual data

Modify /resources/app/data//SCRIPTS.js

Find @ L37886
JavaScript:
"formulas": [
    $(function() {
        if ($dataFields.globalData.cgGallery[o.parent.data[0].index].unlocked) {
            o.image = o.parent.data[0].thumb.name;
            return o.imageFolder = o.parent.data[0].thumb.folderPath;
        }
    }), $(function() {
        if (!$dataFields.globalData.cgGallery[o.parent.data[0].index].unlocked) {
            return o.image = "UI/locked.png";
        }
    })
]
Replace with:

JavaScript:
"formulas": [
    $(function() {
        if (true) {//$dataFields.globalData.cgGallery[o.parent.data[0].index].unlocked
            o.image = o.parent.data[0].thumb.name;
            return o.imageFolder = o.parent.data[0].thumb.folderPath;
        }
    }), $(function() {
        if (false) {//!$dataFields.globalData.cgGallery[o.parent.data[0].index].unlocked
            return o.image = "UI/locked.png";
        }
    })
]
I'm trying to figure out how to do the scenes themselves, so we don't always need a full save, but either I'm done or that's somewhere deeper I haven't found yet. Will update when I find it.
I found this on line 28490
Code:
/**
  * @method commandUnlockCG
  * @protected
   */

and changed the entire loop with this:
JavaScript:
Component_CommandInterpreter.prototype.commandUnlockCG = function() {
  for (var key in RecordManager.cgGallery) {
    var cg = RecordManager.cgGallery[key];
    GameManager.globalData.cgGallery[cg.index] = { unlocked: true };
  }
  return GameManager.saveGlobalData();
};
Not sure if it works tho since I had a bunch of the gallery unlocked and don't know what scenes were missing.
 

Groomtinger

Newbie
Aug 9, 2017
38
167
Not sure if it works tho since I had a bunch of the gallery unlocked and don't know what scenes were missing.
Nah, the cgGallery is referring to the collector cards. Nothing in any of the human-readable files relate to the Scene Gallery, that I could find. Before I gave up, I was looking into the structure of the game variables from the dev console. I could find their definitions, but not where they're set. I'm not super smart, tho.

If you want to enable the dev console yourself to take a look around:

Edit main.js, after:

win.loadFile('index.html')

Put:

win.webContents.openDevTools({ mode: 'detach' });

EDIT:

I just figured out how to decode the json.js files in the resource folders.

Seeing if this is anything useful RQ.

EDIT2:

The same logic to decrypt the json.js files can be successfully applied to all the images and whatnot.

EDIT3:

I. Fucking. Did. It.

himler

Drop and replace this file in /resources/app/data



I'll paste the code I used to make this happen, if you don't want to use my shady URL (I couldn't upload here because it has an unallowed file extension, and I didn't feel like bypassing that was within the spirit of the rules).

DECODE ALL FILES
JavaScript:
const fs = require('fs');
const path = require('path');

const key = [42, 11, 22, 79, 43, 37, 14, 11, 24, 30];
const extractedDir = path.join(__dirname, 'extracted');

if (!fs.existsSync(extractedDir)) {
  fs.mkdirSync(extractedDir);
}

const files = fs.readdirSync(__dirname);
const encryptedFiles = files.filter(f => f.endsWith('.json.js'));

encryptedFiles.forEach(file => {
  const encryptedData = fs.readFileSync(path.join(__dirname, file));
  const decrypted = Buffer.alloc(encryptedData.length);

  for (let i = 0; i < encryptedData.length; i++) {
    decrypted[i] = encryptedData[i] ^ key[i % key.length];
  }

  const outputFileName = file.replace(/\.js$/, '');
  const outputPath = path.join(extractedDir, outputFileName);
  fs.writeFileSync(outputPath, decrypted);

  const content = decrypted.toString('utf8').toLowerCase();
  if (content.includes('scene gallery')) {
    console.log(`Found "gallery" in: ${outputFileName}`);
  }
});
Find the correct file: CD16B1B8867710487F3B6B911CF0477E444F.json

Temporarily remove GS.dataCache['CD16B1B8867710487F3B6B911CF0477E444F'] = at the BEGINNING, beause otherwise it's invalid JSON and we won't be able to parse it.

MODIFY THE GALLERY CONDITION CHECKS
(Basically, this just changes the conditions to be <= 99999)
JavaScript:
const fs = require('fs');
const path = require('path');

const filePath = path.join(__dirname, 'CD16B1B8867710487F3B6B911CF0477E444F.json');

let json;
try {
  const content = fs.readFileSync(filePath, 'utf-8');
  json = JSON.parse(content);
} catch (e) {
  console.error('Failed to read or parse file:', e.message);
  process.exit(1);
}

function modifyConditions(obj) {
  if (Array.isArray(obj)) {
    obj.forEach(modifyConditions);
  } else if (typeof obj === 'object' && obj !== null) {
    if (obj.id === 'gs.Condition' && obj.params) {
      obj.params.operation = 5;
      obj.params.numberValue = 99999;
    }
    Object.values(obj).forEach(modifyConditions);
  }
}

modifyConditions(json);

fs.writeFileSync(filePath, JSON.stringify(json, null, 2), 'utf-8');
console.log('All gs.Condition blocks set to always-true.');
Put GS.dataCache['CD16B1B8867710487F3B6B911CF0477E444F'] = back at the beginning of the file.

RE-ENCRYPT THE FILE:
JavaScript:
const fs = require('fs');

const key = [42, 11, 22, 79, 43, 37, 14, 11, 24, 30];

const fileName = 'CD16B1B8867710487F3B6B911CF0477E444F.json';

const data = fs.readFileSync(fileName);
const encrypted = Buffer.alloc(data.length);

for (let i = 0; i < data.length; i++) {
  encrypted[i] = data[i] ^ key[i % key.length];
}

fs.writeFileSync(fileName + '.js', encrypted);
console.log(`Re-encrypted: ${fileName} → ${fileName}.js`);
Then just toss it back in.

EDIT FINAL:

It is worth noting that, while every new scene will likely invalidate this fix, the METHOD to achieve it will NEVER change (although, the encryption keys COULD be changed, though those are easy to find).
 
Last edited:
  • Like
Reactions: memeLordo and maped
4.30 star(s) 28 Votes