Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added compatibility with mods that inject into PP-related vanilla functions #591

Closed
wants to merge 1 commit into from

Conversation

hyoretsu
Copy link

@hyoretsu hyoretsu commented Feb 20, 2021

Though I just noticed that Cookie Monster would also break with kitten upgrades, checking that.

Injected code into Game.GetTieredCpsMult instead of adding it to a static modified function. Also removed useless parts from CM.Sim.InitialBuildingData.
@hyoretsu
Copy link
Author

hyoretsu commented Feb 20, 2021

It's related to how CM also gets a static copy of Game.CalculateGains(). It'll take some time as it's quite big, but I'll check what's useless from there. (Changing CM.Sim's to vanilla and checking if anything breaks)

@DanielNoord
Copy link
Collaborator

DanielNoord commented Feb 20, 2021

Just thinking out loud here: is there a way to create a "Create Sim-copy" function that can then be called on each Game function to create one where everything is replaced?
I am thinking of one function that stores all possible replacement actions (so Game.Objects to Sim.Objects and Game.Has to Sim.Has) which is then passed functions like Game.CalculateGains() and Game.GetTieredCpsMult()

Edit: just saw that in the commit you replace Game.GetTieredCpsMult() I don't know if this is intended but I think we should still create CM.Sim..GetTieredCpsMult() otherwise the base game will start to use the data stored in CM.Sim instead of Game to calculate CPS and run the game.

@DanielNoord
Copy link
Collaborator

Another problem I just thought of is that using new Function will also result in errors with ESLint as it is basically an eval.
This is also the problem I ran into last time when I wanted to remove all evals.

@hyoretsu
Copy link
Author

Just thinking out loud here: is there a way to create a "Create Sim-copy" function that can then be called on each Game function to create one where everything is replaced?
I am thinking of one function that stores all possible replacement actions (so Game.Objects to Sim.Objects and Game.Has to Sim.Has) which is then passed functions like Game.CalculateGains() and Game.GetTieredCpsMult()

Not as broad as that, but you can use the same method I used to automate that.

new Function(
	`return ${Game.anyFunction.toString()
	.replaceAll(/Game/, 'CM.Sim')}`,
 )();

In an even more automated way:

const gameObjKeys = Object.keys(Game);
const gameObjValues = Object.values(Game);
const CM.Sim = {};

gameObjValues.forEach((originalValue, index) => {
 let injectedFunc;

 if (typeof originalFunc === 'function') {
  injectedFunc = new Function(
   `return ${originalValue.toString()
    .replaceAll(/Game/, 'CM.Sim.')}`,
  )();
 }

 Object.assign(CM.Sim, {
  [gameObjKeys[index]]: injectedFunc || originalValue,
 })
})

That should create a copy of Game with all Game methods changed to CM.Sim, (might need some checking to make sure nothing was changed unintentionally) though it'd probably lag a bit since that's pretty much going through the entire game.

Creating CM.Sim functions in this new Function()() way would be an easy fix for this problem which takes care of injections, especially since you'd already want to do that eventually when optimizing Cookie Monster. But you'd need to have a warning to place Cookie Monster last on loading order/setting a delay as noted by you before, so it isn't that much of a fix. (Although doable)

don't know if this is intended but I think we should still create CM.Sim..GetTieredCpsMult() otherwise the base game will start to use the data stored in CM.Sim instead of Game to calculate CPS and run the game.

I don't know what that'd affect Yeah, CpS changes some time after buying/selling buildings. It was intended, as that'd make the function work with all future injections, but it introduced that bug. Also checking a possible way to fix that.

Another problem I just thought of is that using new Function will also result in errors with ESLint as it is basically an eval.
This is also the problem I ran into last time when I wanted to remove all evals.

For that, it is best to disable no-new-func rule. You already need to disable quite a few rules to work with Orteil code and ESLint. And Are eval() and new Function() the same thing?

@DanielNoord
Copy link
Collaborator

Should indeed be able to do this somewhat automated, although I think I prefer doing it on a per-function basis instead of the full game at once.

We could put the replacing functions into CM.Main.Loop() to circumvent the issue of CM loading before a content mod, although that feels a bit "hacky" an introduces unnecessary functions into the loop (it would only rarely actually be useful).
Perhaps doing something with checking in the loop if the number of registered mods has increased and in that case re-replace all functions might work.

Currently I am only using the recommend set of rules for ESLint. Changing to all or airbnb gave about 10k errors (mostly indentation and style). If I ever change this using no-new-func will probably be necessary indeed.

@DanielNoord
Copy link
Collaborator

I have worked on this some more and have implemented code that recognizes content mods in #592.

Please do tell if any issues remain, but from my personal testing it all seems to work now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants