NiceneNerd / BCML

Breath of the Wild Cross-Platform Mod Loader: A mod merger and manager for BOTW
308 stars 57 forks source link

Options configuration not loading from info.json #189

Closed t3nk3y closed 3 years ago

t3nk3y commented 3 years ago

When an info.json that has an options section is loaded by selecting the directory from the BCML DevTools screen, the Options settings are not loaded from the info file. I'm not sure if this is a missing feature, or a bug.

Either way, any mods that try to use even modest option configs really need the config to load from the info file, as it's too much effort to have to re-enter every option via the gui on each build.

NiceneNerd commented 3 years ago

@t3nk3y This issue and several others I have addressed in a new beta build. I have not had time to test them very thoroughly, so if you want to try the beta out and see how it works, just run BCML using bcml-debug and it will offer to update you to the beta.

t3nk3y commented 3 years ago

I compiled the beta from source, not using bcml-debug, so maybe I should try that again. This feature DOES seem to be working now, however, when I try to build my BNP, I'm getting an Oops! Error screen, with no visible errors in the dialog box.

It does seem to create the BNP though. Any thoughts on how I could help test, and if you want this moved to a new bug? I can supply the source folder that is generating the error.

NiceneNerd commented 3 years ago

If you run with bcml-debug, can you right-click the window anywhere, open developer tools, and watch the console when your get the blank error?

t3nk3y commented 3 years ago

It looks like JS is minified here. I would have expected the -debug version to not be minified. Dying somewhere in here ( For some reason this wont pretty print ) :

(function(t){try{console.error(JSON.stringify(t))}catch(t){console.log(JSON.stringify(t))}e.setState({showProgress:!1,showError:!0,error:t},(function(){return e.refreshMods()}))})),(0,f.default)((0,c.default)(e),"handleInstall",function(){var t=(0,o.default)(a.default.mark((function t(n,r){var o;return a.default.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(e.selects){t.next=9;break}return t.next=3,new Promise((function(t){return e.setState({progressTitle:"One Sec",progressStatus:"Processing",showProgress:!0},(function(){return t()}))}));case 3:return t.next=5,pywebview.api.check_mod_options({mods:n});case 5:return e.selects=t.sent,console.log(e.selects),t.next=9,new Promise((function(t){return e.setState({showProgress:!0},(function(){return t()}))}));case 9:if(!((o=Object.keys(e.selects).length)>0&&(!e.state.selects||o>Object.keys(e.state.selects).length))){t.next=14;break}return e.installArgs={mods:n,options:r},e.setState({selectPath:Object.keys(e.selects)[0],selectMod:e.selects[Object.keys(e.selects)[0]]}),t.abrupt("return");case 14:e.setState({showProgress:!0,progressTitle:"Installing Mod"+(n.length>1?"s":"")},(function(){pywebview.api.install_mod({mods:n,options:r,selects:e.state.selects}).then((function(t){if(!t.success)throw t.error;e.selects=null,e.setState({showProgress:!1,showDone:!0,selects:{}},(function(){return e.refreshMods()}))})).catch(e.showError)}));case 15:case"end":return t.stop()}}),t)})));return function(e,n){return t.apply(this,arguments)}}()),(0,f.default)((0,c.default)(e),"handleBackups",(function(t,n){var r,a;"create"==n?(r="Creating Backup",a=pywebview.api.create_backup):"restore"==n?(r="Restoring ".concat(t.name),a=pywebview.api.restore_backup,t=t.path):(r="Deleting ".concat(t.name),a=pywebview.api.delete_backup,t=t.path);var o=function(){return e.setState({showProgress:"delete"!=n,showBackups:"delete"==n,progressTitle:r},(function(){return a({backup:t}).then((function(t){if(!t.success)throw t.error;e.setState({showProgress:!1,showDone:!0},(function(){e.backupRef.current.refreshBackups(),"restore"==n&&e.refreshMods()}))})).catch(e.showError)}))};"delete"==n?e.confirm("Are you sure you want to delete this backup?",o):o()})),(0,f.default)((0,c.default)(e),"handleOldRestore",(function(){e.setState({showProgress:!0,showBackups:!1,progressTitle:"Restoring BCML 2.8 Backup"},(function(){pywebview.api.restore_old_backup().then((function(t){if(!t.success)throw t.error;e.setState({showProgress:!1,showDone:!0},(function(){return e.refreshMods()}))})).catch(e.showError)}))})),(0,f.default)((0,c.default)(e),"export",(function(){e.setState({showProgress:!0,progressTitle:"Exporting Mods..."},(function(){pywebview.api.export().then((function(t){if(!t.success)throw t.error;e.setState({showProgress:!1,showDone:!0})})).catch(e.showError)}))})),(0,f.default)((0,c.default)(e),"refreshMods",(function(){e.setState({modsLoaded:!1},(function(){pywebview.api.get_mods({disabled:!0}).then((function(t){if(!t.success)throw t.error;e.setState({mods:t.data,modsLoaded:!0})})).catch(e.showError)}))})),(0,f.default)((0,c.default)(e),"launchGame",(function(){pywebview.api.launch_game().then((function(e){if(!e.success)throw e.error})).catch(e.props.onError)})),(0,f.default)((0,c.default)(e),"updateBcml",(function(){e.confirm("Are you sure you want to update BCML? Updating will close the program, run the update, and attempt to lauch it again.",(function(){pywebview.api.update_bcml()}))})),(0,f.default)((0,c.default)(e),"setProgress",(function(t,n){e.setState({progressTitle:t,progressStatus:n||"",showProgress:!0})})),(0,f.default)((0,c.default)(e),"setDone",(function(){e.setState({showProgress:!1,showDone:!0})})),e.state={tab:"mod-list",mods:[],modsLoaded:!1,selects:null,selectMod:null,selectPath:null,settingsLoaded:!1,settings:{},settingsValid:!1,savingSettings:!1,showDone:!1,showBackups:!1,showError:!1,error:null,showProgress:!1,progressStatus:"",progressTitle:"",showConfirm:!1,confirmText:"",confirmCallback:function(){},showAbout:!1,update:!1,changelog:!0,showChangelog:!1,version:"3.0"},e.selects=null,e.backupRef=x.default.createRef(),window.addEventListener("pywebviewready",(function(){setTimeout((0,o.default)(a.default.mark((function t(){var n;return a.default.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,pywebview.api.get_settings();case 2:n=t.sent,console.log(n),e.setState({settings:n},(0,o.default)(a.default.mark((function t(){var n;return a.default.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return console.log("Settings updated"),t.next=3,pywebview.api.get_ver();case 3:n=t.sent,e.setState(T({},n));case 5:case"end":return t.stop()}}),t)}))));case 5:case"end":return t.stop()}}),t)}))),500),setTimeout((function(){e.refreshMods()}),250)})),window.addEventListener("focus",(function(){document.body.focus()})),e}return(0,d.default)(t,e),(0,l.default)(t,[{key:"render",value:function(){var e=this;return x.default.createElement(x.default.Fragment,null,x.default.createElement("div",{className:"overflow-menu d-flex"},x.default.createElement(p.Dropdown,{alignRight:!0},x.default.createElement(p.Dropdown.Toggle,{id:"dropdown-basic",title:"Overflow Menu (Alt+M)"},x.default.createElement("i",{className:"material-icons"},"menu")),x.default.createElement(p.Dropdown.Menu,null,x.default.createElement(p.Dropdown.Item,{onClick:function(){return pywebview.api.save_mod_list()}},"Save Mod List"),x.default.createElement(p.Dropdown.Item,{onClick:this.updateBcml},"Update BCML"),x.default.createElement(p.Dropdown.Item,{as:"a",href:"/index.html?firstrun"},"Run Setup Wizard"),x.default.createElement(p.Dropdown.Item,{onClick:function(){return e.setState({showAbout:!0})}},"About"))),x.default.createElement(p.OverlayTrigger,{overlay:x.default.createElement(p.Tooltip,null,"Help (F1)"),placement:"bottom"},x.default.createElement(p.Button,{size:"xs",variant:"outline text-light",alignRight:!0,onClick:function(){return pywebview.api.open_help()}},x.default.createElement("i",{className:"material-icons"},"help")))),x.default.createElement(y.default.Provider,{value:{mods:this.state.mods,busy:this.state.showProgress,settings:this.state.settings}},x.default.createElement(p.Tabs,{id:"tabs",mountOnEnter:!0,activeKey:this.state.tab,onSelect:function(t){return e.setState({tab:t})},transition:p.Fade},x.default.createElement(p.Tab,{eventKey:"mod-list",title:"Mods"},x.default.createElement(w.default,{onBackup:function(){return e.setState({showBackups:!0})},loaded:this.state.modsLoaded,onRefresh:this.refreshMods,onConfirm:this.confirm,onChange:function(t){return e.setState({mods:t})},onInstall:this.handleInstall,onError:this.showError,onProgress:this.setProgress,onDone:function(){return e.setState({showProgress:!1,showDone:!0})},onCancel:function(){return e.setState({showProgress:!1})},onExport:this.export,onLaunch:this.launchGame})),x.default.createElement(p.Tab,{eventKey:"gamebanana",title:"GameBanana"},x.default.createElement(b.default,{onError:this.showError,onProgress:this.setProgress,onDone:function(){return e.setState({showProgress:!1})}})),x.default.createElement(p.Tab,{eventKey:"dev-tools",title:"Dev Tools"},x.default.createElement(v.default,{onError:this.showError,onProgress:this.setProgress,onCancel:function(){return e.setState({showProgress:!1})},onDone:function(){return e.setState({showProgress:!1,showDone:!0})}})),x.default.createElement(p.Tab,{eventKey:"settings",title:"Settings",className:"p-2"},x.default.createElement(S.default,{saving:this.state.savingSettings,onFail:function(){return e.setState({savingSettings:!1,showError:!0,error:{short:"Your settings are not valid and cannot be saved. Check that all required fields are completed and green before submitting. If you have trouble, consult the in-app help.",error_text:"Your settings are not valid and cannot be saved. Check that all required fields are completed and green before submitting. If you have trouble, consult the in-app help."}})},onSubmit:this.saveSettings,onProgress:this.setProgress,onDone:function(){return e.setState({showProgress:!1})}}),x.default.createElement(p.Button,{className:"fab",onClick:function(){return e.setState({savingSettings:!0})}},x.default.createElement("i",{className:"material-icons"},"save"))))),x.default.createElement(E.default,{show:this.state.showProgress,title:this.state.progressTitle,status:this.state.progressStatus}),x.default.createElement(P,{show:this.state.showDone,onClose:function(){return e.setState({showDone:!1})},onError:this.showError,onLaunch:this.launchGame}),x.default.createElement(g.default,{show:this.state.showError,error:this.state.error,onClose:function(){return e.setState({showError:!1})}}),x.default.createElement(j,{show:this.state.showConfirm,message:this.state.confirmText,onClose:this.state.confirmCallback.bind(this)}),x.default.createElement(M,{show:this.state.update,onClose:function(t){return e.setState({update:!1},(function(){return t?e.updateBcml():null}))}}),x.default.createElement(h.default,{show:this.state.showBackups,busy:this.state.showProgress,ref:this.backupRef,onCreate:this.handleBackups,onRestore:this.handleBackups,onOldRestore:this.handleOldRestore,onDelete:this.handleBackups,onClose:function(){return e.setState({showBackups:!1})}}),x.default.createElement(m.default,{show:this.state.showAbout,onClose:function(){return e.setState({showAbout:!1})},version:this.state.version}),x.default.createElement(C.default,{show:null!=this.state.selectMod,path:this.state.selectPath,mod:this.state.selectMod,onClose:function(){e.setState({selectMod:null,selectPath:null,selects:{},showProgress:!1,showDone:!1}),e.installArgs=null,e.selects=null},onSet:function(t){delete e.selects[e.state.selectPath],e.setState({selectMod:null,selectPath:null,selects:T({},e.state.selects,(0,f.default)({},e.state.selectPath,t))},(function(){e.handleInstall(e.installArgs.mods,e.installArgs.options),e.installArgs=null}))}}),this.state.changelog&&x.default.createElement(D,{show:this.state.showChangelog,onClose:function(){return e.setState({showChangelog:!1})},version:this.state.version}))}}]),t}(x.default.Component),P=function(e){function t(e){var n;return(0,i.default)(this,t),(n=(0,s.default)(this,(0,u.default)(t).call(this,e))).state={hasCemu:!1},n.launch_game=n.launch_game.bind((0,c.default)(n)),n}return(0,d.default)(t,e),(0,l.default)(t,[{key:"componentDidUpdate",value:function(e){var t=this;if(this.props.show!=e.show)try{pywebview.api.get_setup().then((function(e){return t.setState(T({},e))}))}catch(e){}}},{key:"launch_game",value:function(){this.props.onLaunch(),this.props.onClose()}},{key:"render",value:function(){return x.default.createElement(p.Modal,{show:this.props.show,size:"sm",centered:!0,onHide:this.props.onClose},x.default.createElement(p.Modal.Header,{closeButton:!0},x.default.createElement(p.Modal.Title,null,"Done!")),x.default.createElement(p.Modal.Footer,null,x.default.createElement(p.Button,{variant:"primary",onClick:this.props.onClose},"OK"),this.state.hasCemu&&x.default.createElement(p.Button,{variant:"secondary",onClick:this.launch_game},"Launch Game")))}}]),t}(x.default.Component),j=function(e){return x.default.createElement(p.Modal,{show:e.show,onHide:e.onClose},x.default.createElement(p.Modal.Header,{closeButton:!0},x.default.createElement(p.Modal.Title,null,"Please Confirm")),x.default.createElement(p.Modal.Body,null,e.message),x.default.createElement(p.Modal.Footer,null,x.default.createElement(p.Button,{onClick:function(){return e.onClose(!0)}},"OK"),x.default.createElement(p.Button,{variant:"secondary",onClick:function(){return e.onClose(!1)}},"Close")))},M=function(e){return x.default.createElement(p.Modal,{show:e.show},x.default.createElement(p.Modal.Header,null,x.default.createElement(p.Modal.Title,null,"Update Available")),x.default.createElement(p.Modal.Body,null,"There is a new update available for BCML. Would you like to install it?"),x.default.createElement(p.Modal.Footer,null,x.default.createElement(p.Button,{onClick:function(){return e.onClose(!0)}},"OK"),x.default.createElement(p.Button,{variant:"secondary",onClick:function(){return e.onClose(!1)}},"Close")))},D=function(e){function t(e){var n;return(0,i.default)(this,t),n=(0,s.default)(this,(0,u.default)(t).call(this,e)),(0,f.default)((0,c.default)(n),"componentDidUpdate",function(){var e=(0,o.default)(a.default.mark((function e(t){var r,o;return a.default.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(n.props.version==t.version){e.next=14;break}return e.prev=1,e.next=4,fetch("https://api.github.com/repos/NiceneNerd/BCML/releases?per_page=5");case 4:return e.next=6,e.sent.json();case 6:r=e.sent,console.log(r),o=r.find((function(e){return e.tag_name.substring(1,7)==n.props.version.trim()})),n.setState({info:o}),e.next=14;break;case 12:e.prev=12,e.t0=e.catch(1);case 14:case"end":return e.stop()}}),e,null,[[1,12]])})));return function(t){return e.apply(this,arguments)}}()),(0,f.default)((0,c.default)(n),"render",(function(){var e,t,r;return null!==(e=n.state.info)&&void 0!==e&&e.body?x.default.createElement(p.Modal,{show:n.props.show},x.default.createElement(p.Modal.Header,{closeButton:!0},x.default.createElement(p.Modal.Title,null,"BCML Updated")),x.default.createElement(p.Modal.Body,null,x.default.createElement("p",null,"BCML has been updated to ",null===(t=n.state.info)||void 0===t?void 0:t.tag_name,". Changelog:"),x.default.createElement(k.default,null,null===(r=n.state.info)||void 0===r?void 0:r.body)),x.default.createElement(p.Modal.Footer,null,x.default.createElement(p.Button,{onClick:function(){return n.props.onClose()}},"OK"))):x.default.createElement(x.default.Fragment,null)})),n.state={info:{}},n}return(0,d.default)(t,e),t}(x.default.Component),F=N;t.default=F},function(e,t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function r(t){return"function"==typeof Symbol&&"symbol"===n(Symbol.iterator)?e.exports=r=function(e){return n(e)}:e.exports=r=function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":n(e)},r(t)}e.exports=r},function(e,t){function n(t,r){return e.exports=n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},n(t,r)}e.exports=n},function(e,t,n){"use strict";

This is just after:

/*
object-assign
(c) Sindre Sorhus
@license MIT
*/

Console log entries below, but, I don't think this is going to be at all helpful.

TypeError: Cannot read property 'map' of undefined
    at t.value (bundle.js:60)
    at Mi (bundle.js:52)
    at ji (bundle.js:52)
    at Il (bundle.js:52)
    at ts (bundle.js:52)
    at Zl (bundle.js:52)
    at Hl (bundle.js:52)
    at bundle.js:52
    at t.unstable_runWithPriority (bundle.js:60)
    at Ba (bundle.js:52)
qi @ bundle.js:52
o.componentDidCatch.n.callback @ bundle.js:52
uo @ bundle.js:52
so @ bundle.js:52
os @ bundle.js:52
t.unstable_runWithPriority @ bundle.js:60
Ba @ bundle.js:52
as @ bundle.js:52
Hl @ bundle.js:52
(anonymous) @ bundle.js:52
t.unstable_runWithPriority @ bundle.js:60
Ba @ bundle.js:52
za @ bundle.js:52
La @ bundle.js:52
Rl @ bundle.js:52
enqueueSetState @ bundle.js:52
E.setState @ bundle.js:44
(anonymous) @ bundle.js:60
Promise.then (async)
(anonymous) @ bundle.js:60
h @ bundle.js:52
E @ bundle.js:52
(anonymous) @ bundle.js:52
S @ bundle.js:52
N @ bundle.js:52
T @ bundle.js:52
P @ bundle.js:52
vn @ bundle.js:52
ue @ bundle.js:52
xn @ bundle.js:52
Cn @ bundle.js:52
kn @ bundle.js:52
t.unstable_runWithPriority @ bundle.js:60
Ba @ bundle.js:52
Vl @ bundle.js:52
wn @ bundle.js:52

  | (anonymous) | @ | bundle.js:36
-- | -- | -- | --
  | (anonymous) | @ | bundle.js:36
  | o.componentDidCatch.n.callback | @ | bundle.js:52
  | uo | @ | bundle.js:52
  | so | @ | bundle.js:52
  | os | @ | bundle.js:52
  | t.unstable_runWithPriority | @ | bundle.js:60
  | Ba | @ | bundle.js:52
  | as | @ | bundle.js:52
  | Hl | @ | bundle.js:52
  | (anonymous) | @ | bundle.js:52
  | t.unstable_runWithPriority | @ | bundle.js:60
  | Ba | @ | bundle.js:52
  | za | @ | bundle.js:52
  | La | @ | bundle.js:52
  | Rl | @ | bundle.js:52
  | enqueueSetState | @ | bundle.js:52
  | E.setState | @ | bundle.js:44
  | (anonymous) | @ | bundle.js:60
  | Promise.then (async) |   |  
  | (anonymous) | @ | bundle.js:60
  | h | @ | bundle.js:52
  | E | @ | bundle.js:52
  | (anonymous) | @ | bundle.js:52
  | S | @ | bundle.js:52
  | N | @ | bundle.js:52
  | T | @ | bundle.js:52
  | P | @ | bundle.js:52
  | vn | @ | bundle.js:52
  | ue | @ | bundle.js:52
  | xn | @ | bundle.js:52
  | Cn | @ | bundle.js:52
  | kn | @ | bundle.js:52
  | t.unstable_runWithPriority | @ | bundle.js:60
  | Ba | @ | bundle.js:52
  | Vl | @ | bundle.js:52
  | wn | @ | bundle.js:52

I'm also seeing a lot of this in both the terminal and the js console:

js: Uncaught TypeError: channel.execCallbacks[message.id] is not a function
t3nk3y commented 3 years ago

I just sent you a PM on GameBanana with a link to a 7z with the directory I'm working using in this test. It's a couple hundred megs, so I don't think I can attach it here on github.

t3nk3y commented 3 years ago

I've also found that once that error message occurs, if I go to the main tab, and click the arrow next to the remerge button, the menu does not open. The menu DOES work when I first open BCML.

t3nk3y commented 3 years ago

And, another update for you. This is probably a bit more helpful. I can reproduce the same error by opening any mod folder that does NOT have any options setup. The moment I open any of those folders, I get the error, and it fails to open the folder. I tested that with several mods, including the one I sent you earlier, all I had to do, was remove the options folder and data from the info.

NiceneNerd commented 3 years ago

I'm about to look at all this, but a question: Are you in the BOTW modding Discord?

t3nk3y commented 3 years ago

I'm about to look at all this, but a question: Are you in the BOTW modding Discord?

I'm on the Zelda's Ballad and Second Wind discord server. Not sure which server is the "BOTW modding Discord", but that sure sounds like a helpful resource to have.

NiceneNerd commented 3 years ago

https://discord.gg/ZkyPWnyN

NiceneNerd commented 3 years ago

lol, the problem was Array.prototype.flatMap() not being available in CEF 66. Sheesh. Easy fix, though.

t3nk3y commented 3 years ago

Did you fix this before the 3.6.0 release? I'm still seeing the same map related error after that update. I get the error when I try to build a mod with options, or when I try to browse to a mod without options(from the Dev Tools tab)