diff --git a/modules/core/render-backend/index.ts b/modules/core/render-backend/index.ts index af44619..cb9ab9e 100644 --- a/modules/core/render-backend/index.ts +++ b/modules/core/render-backend/index.ts @@ -10,6 +10,7 @@ import {processArguments} from "../../shared/process-arguments"; import "./ExternalModal"; import {showUpdateWindow} from "../windows/client-updater/controller/ClientUpdate"; +import {getUiFilePath} from "../ui-loader/Loader"; ipcMain.on('basic-action', (event, action, ...args: any[]) => { const window = BrowserWindow.fromWebContents(event.sender); @@ -27,4 +28,6 @@ ipcMain.on('basic-action', (event, action, ...args: any[]) => { } else if(action === "quit") { window.close(); } -}); \ No newline at end of file +}); + +ipcMain.handle("tc-get-ui-path", () => getUiFilePath()); \ No newline at end of file diff --git a/modules/core/ui-loader/Loader.ts b/modules/core/ui-loader/Loader.ts index c6d99b2..266e32b 100644 --- a/modules/core/ui-loader/Loader.ts +++ b/modules/core/ui-loader/Loader.ts @@ -125,8 +125,14 @@ async function unpackLocalUiPack(version: CachedUIPack) : Promise { return targetDirectory; } +let uiFilePath: string; +export function getUiFilePath() : string | undefined { + return uiFilePath; +} + function initializeFileSystemProtocol(directory: string) { directory = path.normalize(directory); + uiFilePath = directory; protocol.registerFileProtocol(kUiPackProtocol, (request, callback) => { let targetPath; diff --git a/modules/renderer/audio/Sounds.ts b/modules/renderer/audio/Sounds.ts index 8079092..6e5482a 100644 --- a/modules/renderer/audio/Sounds.ts +++ b/modules/renderer/audio/Sounds.ts @@ -1,27 +1,52 @@ import {audio as naudio} from "tc-native/connection"; import {SoundBackend, SoundFile} from "tc-shared/audio/Sounds"; import * as paths from "path"; +import * as loader from "tc-loader"; +import {Stage} from "tc-loader"; +import {ipcRenderer} from "electron"; +import {LogCategory, logDebug, logInfo} from "tc-shared/log"; +let uiFilePath; export class NativeSoundBackend implements SoundBackend { playSound(sound: SoundFile): Promise { return new Promise((resolve, reject) => { - let pathname = paths.dirname(decodeURIComponent(location.pathname)); - if(pathname[0] === '/' && pathname[2] === ':') //e.g.: /C:/test... - pathname = pathname.substr(1); - const path = paths.join(pathname, sound.path); + if(!uiFilePath) { + reject("Mussing UI file path"); + return; + } - console.log("replaying %s (volume: %f)", sound.path, sound.volume); + const path = paths.join(uiFilePath, sound.path); + console.log("replaying %s (volume: %f) from %s", sound.path, sound.volume, path); naudio.sounds.playback_sound({ callback: (result, message) => { - if(result == naudio.sounds.PlaybackResult.SUCCEEDED) + if(result == naudio.sounds.PlaybackResult.SUCCEEDED) { resolve(); - else + } else { reject(naudio.sounds.PlaybackResult[result].toLowerCase() + ": " + message); + } }, file: path, volume: typeof sound.volume === "number" ? sound.volume : 1 }); }); } +} -} \ No newline at end of file +//tc-get-ui-path +loader.register_task(Stage.JAVASCRIPT_INITIALIZING, { + name: "sound initialize", + priority: 50, + function: async () => { + uiFilePath = await ipcRenderer.invoke("tc-get-ui-path"); + if(!uiFilePath) { + logInfo(LogCategory.AUDIO, tr("Missing UI path. App sounds will not work.")); + } else { + if(uiFilePath[0] === '/' && uiFilePath[2] === ':') { + //e.g.: /C:/test... + uiFilePath = uiFilePath.substr(1); + } + + logDebug(LogCategory.AUDIO, tr("Received UI path: %s"), uiFilePath); + } + } +}) \ No newline at end of file diff --git a/native/serverconnection/src/audio/AudioOutput.cpp b/native/serverconnection/src/audio/AudioOutput.cpp index 6ff4564..c6ac8a6 100644 --- a/native/serverconnection/src/audio/AudioOutput.cpp +++ b/native/serverconnection/src/audio/AudioOutput.cpp @@ -270,7 +270,7 @@ ssize_t AudioOutputSource::enqueue_samples_no_interleave(const void *source_buff bool AudioOutputSource::set_max_buffered_samples(size_t samples) { samples = std::max(samples, (size_t) this->fadein_frame_samples_); if(samples > this->max_supported_buffering()) { - return false; + samples = this->max_supported_buffering(); } std::lock_guard buffer_lock{this->buffer_mutex}; diff --git a/native/serverconnection/src/audio/sounds/SoundPlayer.cpp b/native/serverconnection/src/audio/sounds/SoundPlayer.cpp index dd269eb..c853827 100644 --- a/native/serverconnection/src/audio/sounds/SoundPlayer.cpp +++ b/native/serverconnection/src/audio/sounds/SoundPlayer.cpp @@ -87,8 +87,9 @@ namespace tc::audio::sounds { this->file_handle = std::make_unique(this->settings_.file); std::string error{}; if(auto err{this->file_handle->open_file(error)}; err != file::OPEN_RESULT_SUCCESS) { - if(auto callback{this->settings_.callback}; callback) + if(auto callback{this->settings_.callback}; callback) { callback(PlaybackResult::FILE_OPEN_ERROR, error); + } this->finalize(false); return; } @@ -175,21 +176,27 @@ namespace tc::audio::sounds { auto weak_this = this->weak_from_this(); this->output_source->on_underflow = [weak_this](size_t sample_count){ auto self = weak_this.lock(); - if(!self) return false; + if(!self) { + return false; + } - if(self->state_ == PLAYER_STATE_PLAYING) + if(self->state_ == PLAYER_STATE_PLAYING) { log_warn(category::audio, tr("Having an audio underflow while playing a sound.")); - else if(self->state_ == PLAYER_STATE_AWAIT_FINISH) + } else if(self->state_ == PLAYER_STATE_AWAIT_FINISH) { self->state_ = PLAYER_STATE_FINISHED; + } audio::decode_event_loop->schedule(self); return false; }; this->output_source->on_read = [weak_this] { auto self = weak_this.lock(); - if(!self) return; + if(!self) { + return; + } - if(self->could_enqueue_next_buffer() && self->state_ == PLAYER_STATE_PLAYING) + if(self->could_enqueue_next_buffer() && self->state_ == PLAYER_STATE_PLAYING) { audio::decode_event_loop->schedule(self); + } }; this->output_source->on_overflow = [weak_this](size_t count) { @@ -205,7 +212,9 @@ namespace tc::audio::sounds { } [[nodiscard]] inline bool could_enqueue_next_buffer() const { - if(!this->output_source) return false; + if(!this->output_source) { + return false; + } const auto current_size = this->output_source->currently_buffered_samples(); const auto max_size = this->output_source->max_buffered_samples(); @@ -233,8 +242,9 @@ namespace tc::audio::sounds { auto player = std::make_shared(settings); file_players.push_back(player); if(!player->play()) { - if(auto callback{settings.callback}; callback) + if(auto callback{settings.callback}; callback) { callback(PlaybackResult::PLAYBACK_ERROR, "failed to start playback."); + } return 0; } fplock.unlock(); @@ -244,7 +254,9 @@ namespace tc::audio::sounds { void cancel_playback(const sound_playback_id& id) { std::unique_lock fplock{file_player_mutex}; auto player_it = std::find_if(file_players.begin(), file_players.end(), [&](const auto& player) { return (sound_playback_id) &*player == id; }); - if(player_it == file_players.end()) return; + if(player_it == file_players.end()) { + return; + } auto player = *player_it; file_players.erase(player_it);