@@ -1214789,6 +1214789,9 @@ jl_Integer_parseInt = $s => {
12147891214789 }
12147901214790 main: while (true) { switch ($ptr) {
12147911214791 case 0:
1214792+ /* Fix 94: strip locale thousands-separator commas (e.g. "1,110" → "1110") */
1214793+ if ($s && typeof $s.$nativeString === 'string' && $s.$nativeString.indexOf(',') >= 0)
1214794+ $s = $rt_str($s.$nativeString.replace(/,/g, ''));
12147921214795 jl_Integer_$callClinit();
12147931214796 var$2 = 10;
12147941214797 $ptr = 1;
@@ -1608419,7 +1608422,7 @@ jn_URLEncoder_encode0 = ($s, $enc) => {
16084191608422 main: while (true) { switch ($ptr) {
16084201608423 case 0:
16084211608424 /* Fix 86: convert non-TeaVM values to TeaVM string for URL encoding */
1608422- if ($s === undefined || $ s === null || typeof $s === 'string' || typeof $s === 'number') $s = $rt_str($s == null ? '' : String($s));
1608425+ if (! $s || typeof $s.$length !== 'function') $s = $rt_str($ s === null || $s === undefined ? '' : ( typeof $s === 'object' && $s.$nativeString ? $s.$nativeString : String($s))); /* Fix 94: robust URLEncoder — handles HashMap/objects */
16084231608426 ju_Objects_requireNonNull($s);
16084241608427 ju_Objects_requireNonNull($enc);
16084251608428 $buf = new jl_StringBuffer;
@@ -1608513,7 +1608516,7 @@ jn_URLEncoder_encode = ($s, $enc) => {
16085131608516 main: while (true) { switch ($ptr) {
16085141608517 case 0:
16085151608518 /* Fix 86b: convert non-TeaVM values to TeaVM string */
1608516- if ($s === undefined || $ s === null || typeof $s === 'string' || typeof $s === 'number') $s = $rt_str($s == null ? '' : String($s));
1608519+ if (! $s || typeof $s.$length !== 'function') $s = $rt_str($ s === null || $s === undefined ? '' : ( typeof $s === 'object' && $s.$nativeString ? $s.$nativeString : String($s))); /* Fix 94: robust URLEncoder — handles HashMap/objects */
16085171608520 ju_Objects_requireNonNull($s);
16085181608521 ju_Objects_requireNonNull($enc);
16085191608522 try {
@@ -1695412,6 +1695415,21 @@ cpr_RPGMain.prototype.$checkForDelayedBootData = function() {
16954121695415 console.info('[Fix88] Heroes injected:', bootData.heroes.length);
16954131695416 }
16954141695417 } catch(heroErr) { console.warn('[Fix88] Hero injection error:', heroErr); }
1695418+ /* Fix 94: populate User object (name, level, resources) from bootData BEFORE refreshUserInfo */
1695419+ try {
1695420+ const _bd = window._dsBootData;
1695421+ const _user = cpr_RPG_app && cpr_RPG_app.$user2;
1695422+ if (_user && _bd) {
1695423+ if (_bd.user_id) _user.$userID0 = Long_fromNumber(_bd.user_id);
1695424+ if (_bd.name) _user.$userName = $rt_str(_bd.name);
1695425+ if ((_bd.team_level||0) > 0) _user.$teamLevel1 = _bd.team_level|0;
1695426+ cprnm_ResourceType_$callClinit();
1695427+ if (_bd.gold !== undefined) cprgo_User_setResource0(_user, cprnm_ResourceType_GOLD, _bd.gold|0, 0);
1695428+ if (_bd.diamonds !== undefined) cprgo_User_setResource0(_user, cprnm_ResourceType_DIAMONDS, _bd.diamonds|0, 0);
1695429+ if (_bd.stamina !== undefined) cprgo_User_setResource0(_user, cprnm_ResourceType_STAMINA, _bd.stamina|0, 0);
1695430+ console.info('[Fix94] User populated: name=' + (_bd.name||'?') + ' lvl=' + (_bd.team_level||0) + ' gold=' + (_bd.gold||0) + ' diamonds=' + (_bd.diamonds||0));
1695431+ }
1695432+ } catch(_uErr) { console.warn('[Fix94] User population error:', _uErr.message||_uErr); }
16954151695433 juca_AtomicReference_set(this.$delayedBootData, bd);
16954161695434 console.info('[Fix88] BootData injected into delayedBootData');
16954171695435 } catch(e) { console.error('[Fix88] BootData injection failed:', e); }
@@ -1702121,27 +1702139,135 @@ function _setupWebGL2Bridge(canvas) {
17021211702139 WebGraphics.prototype.$getFramesPerSecond = function() { return 60; };
17021221702140 WebGraphics.prototype.$getRawDeltaTime = function() { return this.$getDeltaTime(); };
17021231702141 }
1702124- if (typeof WebAudio !== 'undefined') {
1702125- // Stub WebAudio methods to prevent crash on sound playback
1702126- WebAudio.prototype.$newSound = function(file) { return window._fakeAudioDevice; };
1702127- WebAudio.prototype.$newMusic = function(file) { return window._fakeAudioDevice; };
1702128- }
1702142+ // Fix 94: Web Audio API engine (replaces no-op stubs)
1702143+ (function() {
1702144+ let _audioCtx = null;
1702145+ function getCtx() {
1702146+ if (!_audioCtx) {
1702147+ try { _audioCtx = new (window.AudioContext || window.webkitAudioContext)(); } catch(e) { return null; }
1702148+ }
1702149+ if (_audioCtx.state === 'suspended') _audioCtx.resume().catch(()=>{});
1702150+ return _audioCtx;
1702151+ }
1702152+ const _bufCache = {};
1702153+ function loadBuffer(path, cb) {
1702154+ const fname = path.split('/').pop();
1702155+ const key = 'sound/' + fname;
1702156+ if (_bufCache[key]) { cb(_bufCache[key]); return; }
1702157+ const ctx = getCtx();
1702158+ if (!ctx) { cb(null); return; }
1702159+ fetch('assets/sound/' + fname)
1702160+ .then(r => r.ok ? r.arrayBuffer() : Promise.reject(r.status))
1702161+ .then(buf => ctx.decodeAudioData(buf))
1702162+ .then(decoded => { _bufCache[key] = decoded; cb(decoded); })
1702163+ .catch(() => cb(null));
1702164+ }
1702165+ function WebAudioSoundImpl(path) {
1702166+ this._path = path; this._buf = null; this._vol = 1.0;
1702167+ this._sources = {}; this._nextId = 1;
1702168+ loadBuffer(path, buf => { this._buf = buf; });
1702169+ }
1702170+ WebAudioSoundImpl.prototype.$play = function() { return this.$play0(this._vol, 1.0, 0.0); };
1702171+ WebAudioSoundImpl.prototype.$play0 = function(vol, pitch, pan) {
1702172+ const ctx = getCtx(); if (!ctx || !this._buf) return -1;
1702173+ const src = ctx.createBufferSource();
1702174+ src.buffer = this._buf;
1702175+ src.playbackRate.value = pitch || 1.0;
1702176+ const gain = ctx.createGain(); gain.gain.value = vol !== undefined ? vol : 1.0;
1702177+ src.connect(gain); gain.connect(ctx.destination);
1702178+ const id = this._nextId++;
1702179+ this._sources[id] = src;
1702180+ src.onended = () => { delete this._sources[id]; };
1702181+ src.start(0); return id;
1702182+ };
1702183+ WebAudioSoundImpl.prototype.$stop = function() {
1702184+ Object.values(this._sources).forEach(s => { try{s.stop();}catch(e){} }); this._sources = {};
1702185+ };
1702186+ WebAudioSoundImpl.prototype.$stop0 = function(id) {
1702187+ if (this._sources[id]) { try{this._sources[id].stop();}catch(e){} delete this._sources[id]; }
1702188+ };
1702189+ WebAudioSoundImpl.prototype.$pause = function() {};
1702190+ WebAudioSoundImpl.prototype.$pause0 = function(id) {};
1702191+ WebAudioSoundImpl.prototype.$resume = function() {};
1702192+ WebAudioSoundImpl.prototype.$resume0 = function(id) {};
1702193+ WebAudioSoundImpl.prototype.$dispose = function() { this.$stop(); };
1702194+ WebAudioSoundImpl.prototype.$setLooping = function(id, loop) { if(this._sources[id]) this._sources[id].loop=!!loop; };
1702195+ WebAudioSoundImpl.prototype.$setVolume = function(id, vol) {};
1702196+ WebAudioSoundImpl.prototype.$setPitch = function(id, pitch) {};
1702197+ WebAudioSoundImpl.prototype.$setPan = function(id, pan, vol) {};
1702198+ WebAudioSoundImpl.prototype.$isPlaying = function(id) { return this._sources[id] ? 1 : 0; };
1702199+ WebAudioSoundImpl.prototype.$isLooping = function(id) { return 0; };
1702200+ WebAudioSoundImpl.prototype.$getVolume = function() { return this._vol; };
1702201+ WebAudioSoundImpl.prototype.$getPosition = function() { return 0.0; };
1702202+ WebAudioSoundImpl.prototype.$setPosition = function(p) {};
1702203+ function WebAudioMusicImpl(path) {
1702204+ this._path = path; this._buf = null; this._src = null;
1702205+ this._gain = null; this._vol = 1.0; this._loop = false;
1702206+ this._playing = false; this._offset = 0; this._startTime = 0;
1702207+ loadBuffer(path, buf => { this._buf = buf; if (this._playing) this._doPlay(); });
1702208+ }
1702209+ WebAudioMusicImpl.prototype._doPlay = function() {
1702210+ const ctx = getCtx(); if (!ctx || !this._buf) { this._playing = true; return; }
1702211+ if (this._src) { try{this._src.stop();}catch(e){} }
1702212+ this._src = ctx.createBufferSource();
1702213+ this._src.buffer = this._buf; this._src.loop = this._loop;
1702214+ this._gain = ctx.createGain(); this._gain.gain.value = this._vol;
1702215+ this._src.connect(this._gain); this._gain.connect(ctx.destination);
1702216+ this._startTime = ctx.currentTime;
1702217+ this._src.start(0, this._offset || 0);
1702218+ this._src.onended = () => { if(!this._loop) { this._playing = false; this._offset = 0; } };
1702219+ };
1702220+ WebAudioMusicImpl.prototype.$play = function() { if(this._playing) return; this._playing=true; if(this._buf) this._doPlay(); };
1702221+ WebAudioMusicImpl.prototype.$stop = function() {
1702222+ if(this._src){try{this._src.stop();}catch(e){} this._src=null;}
1702223+ this._playing=false; this._offset=0;
1702224+ };
1702225+ WebAudioMusicImpl.prototype.$pause = function() {
1702226+ if(!this._playing||!this._src) return;
1702227+ const ctx=getCtx(); if(ctx) this._offset=ctx.currentTime-this._startTime;
1702228+ try{this._src.stop();}catch(e){} this._src=null; this._playing=false;
1702229+ };
1702230+ WebAudioMusicImpl.prototype.$resume = function() { this.$play(); };
1702231+ WebAudioMusicImpl.prototype.$dispose = function() { this.$stop(); this._buf=null; };
1702232+ WebAudioMusicImpl.prototype.$isPlaying = function() { return this._playing ? 1 : 0; };
1702233+ WebAudioMusicImpl.prototype.$isLooping = function() { return this._loop ? 1 : 0; };
1702234+ WebAudioMusicImpl.prototype.$setLooping = function(v) { this._loop=!!v; if(this._src) this._src.loop=this._loop; };
1702235+ WebAudioMusicImpl.prototype.$setVolume = function(v) { this._vol=v; if(this._gain) this._gain.gain.value=v; };
1702236+ WebAudioMusicImpl.prototype.$getVolume = function() { return this._vol; };
1702237+ WebAudioMusicImpl.prototype.$setPosition = function(p) {
1702238+ const was=this._playing; if(was) this.$stop(); this._offset=p;
1702239+ if(was){this._playing=true; if(this._buf) this._doPlay();}
1702240+ };
1702241+ WebAudioMusicImpl.prototype.$getPosition = function() {
1702242+ const ctx=getCtx();
1702243+ if(!ctx||!this._playing||!this._src) return this._offset;
1702244+ return this._offset+(ctx.currentTime-this._startTime);
1702245+ };
1702246+ if (typeof WebAudio !== 'undefined') {
1702247+ WebAudio.prototype.$newSound = function(file) {
1702248+ const path = (file && file.$path0) ? $rt_ustr(file.$path0) : null;
1702249+ if (!path) return window._fakeAudioDevice;
1702250+ return new WebAudioSoundImpl(path);
1702251+ };
1702252+ WebAudio.prototype.$newMusic = function(file) {
1702253+ const path = (file && file.$path0) ? $rt_ustr(file.$path0) : null;
1702254+ if (!path) return window._fakeAudioDevice;
1702255+ return new WebAudioMusicImpl(path);
1702256+ };
1702257+ console.info('[WebAudio] Fix94: Web Audio API engine ready');
1702258+ }
1702259+ })();
17021291702260 window._fakeAudioDevice = {
1702130- $play: function() {},
1702131- $stop: function() {},
1702132- $pause: function() {},
1702133- $resume: function() {},
1702261+ $play: function() { return -1; }, $play0: function(v,p,pan) { return -1; },
1702262+ $stop: function() {}, $stop0: function(id) {},
1702263+ $pause: function() {}, $pause0: function(id) {},
1702264+ $resume: function() {}, $resume0: function(id) {},
17021341702265 $dispose: function() {},
1702135- $setLooping: function(v) {},
1702136- $setVolume: function(v) {},
1702137- $setPitch: function(v) {},
1702138- $setPan: function(p,v) {},
1702139- $isPlaying: function() { return 0; },
1702140- $isLooping: function() { return 0; },
1702141- $getVolume: function() { return 1.0; },
1702142- $getPosition: function() { return 0.0; },
1702266+ $setLooping: function(id,v) {}, $setVolume: function(id,v) {},
1702267+ $setPitch: function(id,v) {}, $setPan: function(id,p,v) {},
1702268+ $isPlaying: function(id) { return 0; }, $isLooping: function(id) { return 0; },
1702269+ $getVolume: function() { return 1.0; }, $getPosition: function() { return 0.0; },
17021431702270 $setPosition: function(p) {},
1702144- $play0: function(v, p, pan) { return -1; }, // Sound.play(float,float,float)
17021451702271 };
17021461702272 // Phase 3.13: WebGL30 VAO bridge (separate class from WebGL20)
17021471702273 if (typeof WebGL30 !== 'undefined') {
0 commit comments