diff options
| author | Tom Pratt <tom.pratt@outlook.com> | 2026-05-12 12:58:44 -0700 |
|---|---|---|
| committer | Tom Pratt <tompratt@squareup.com> | 2026-05-19 12:03:01 +0200 |
| commit | 4c0bf2944bedb428dd46db4cb39ea5dd9d5d8c98 (patch) | |
| tree | 22a255e9112e8b9b5d69ef281456a4b08f83fc00 /Source/Android/app/src/main | |
| parent | 76ae44569415c0ffb674d184312ea898aab92a18 (diff) | |
Implement DoAllPlayersHaveGame() check
Diffstat (limited to 'Source/Android/app/src/main')
5 files changed, 52 insertions, 2 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/NetplaySession.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/NetplaySession.kt index 0ba5d409b0..f06ec033dc 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/NetplaySession.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/NetplaySession.kt @@ -170,6 +170,8 @@ class NetplaySession( fun changeGame(gameFile: GameFile) = nativeChangeGame(gameFile) + fun doAllPlayersHaveGame(): Boolean = nativeDoAllPlayersHaveGame() + fun startGame() = nativeStartGame() fun getPort(): Int = nativeGetPort() @@ -261,6 +263,8 @@ class NetplaySession( private external fun nativeChangeGame(gameFile: GameFile) + private external fun nativeDoAllPlayersHaveGame(): Boolean + private external fun nativeStartGame() private external fun nativeGetPort(): Int diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/NetplayViewModel.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/NetplayViewModel.kt index 9f9b422f4b..adea1a13a5 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/NetplayViewModel.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/NetplayViewModel.kt @@ -9,7 +9,9 @@ import androidx.lifecycle.viewModelScope import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.launchIn @@ -99,7 +101,18 @@ class NetplayViewModel( } } + private val _notAllPlayersHaveGame = Channel<Unit>(Channel.CONFLATED) + val notAllPlayersHaveGame = _notAllPlayersHaveGame.receiveAsFlow() + fun startGame() { + if (netplaySession.doAllPlayersHaveGame()) { + netplaySession.startGame() + } else { + _notAllPlayersHaveGame.trySend(Unit) + } + } + + fun confirmStartGame() { netplaySession.startGame() } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayActivity.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayActivity.kt index fe38cfe067..eb9cecec20 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayActivity.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayActivity.kt @@ -9,7 +9,6 @@ import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.livedata.observeAsState import androidx.lifecycle.Lifecycle import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.flowWithLifecycle @@ -49,15 +48,17 @@ class NetplayActivity : AppCompatActivity(), ThemeProvider { DolphinTheme { NetplayScreen( onBackClicked = { finish() }, + isHosting = viewModel.isHosting, connectionLost = viewModel.connectionLost, fatalTraversalError = viewModel.fatalTraversalError, messages = viewModel.messages.collectAsState().value, onSendMessage = viewModel::sendMessage, game = viewModel.game.collectAsState().value, - isHosting = viewModel.isHosting, onStartGame = viewModel::startGame, onGameSelected = viewModel::changeGame, gameFiles = viewModel.gameFiles.collectAsState().value, + notAllPlayersHaveGame = viewModel.notAllPlayersHaveGame, + onConfirmStartGame = viewModel::confirmStartGame, players = viewModel.players.collectAsState().value, hostInputAuthorityEnabled = viewModel.hostInputAuthority.collectAsState().value, networkMode = viewModel.networkMode.collectAsState().value, diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt index 3be5cb0618..5d94a29463 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt @@ -121,6 +121,8 @@ fun NetplayScreen( onStartGame: () -> Unit, onGameSelected: (GameFile) -> Unit, gameFiles: List<GameFile>, + notAllPlayersHaveGame: Flow<Unit>, + onConfirmStartGame: () -> Unit, hostInputAuthorityEnabled: Boolean, networkMode: NetworkMode, onNetworkModeChanged: (NetworkMode) -> Unit, @@ -229,6 +231,11 @@ fun NetplayScreen( fatalTraversalError.collect { traversalError = it } } + var showNotAllPlayersHaveGame by rememberSaveable { mutableStateOf(false) } + LaunchedEffect(Unit) { + notAllPlayersHaveGame.collect { showNotAllPlayersHaveGame = true } + } + var dismissSaveTransferProgressDialog by rememberSaveable { mutableStateOf(false) } if (saveTransferProgress == null) { dismissSaveTransferProgressDialog = false @@ -279,6 +286,27 @@ fun NetplayScreen( onDismiss = { dismissGameDigestDialog = true }, ) } + + showNotAllPlayersHaveGame -> { + AlertDialog( + title = { Text(stringResource(R.string.netplay_start_warning_title)) }, + text = { Text(stringResource(R.string.netplay_start_warning_not_all_players_have_game)) }, + confirmButton = { + TextButton(onClick = { + showNotAllPlayersHaveGame = false + onConfirmStartGame() + }) { + Text(stringResource(R.string.yes)) + } + }, + dismissButton = { + TextButton(onClick = { showNotAllPlayersHaveGame = false }) { + Text(stringResource(R.string.no)) + } + }, + onDismissRequest = { showNotAllPlayersHaveGame = false }, + ) + } } } } @@ -1280,6 +1308,8 @@ private fun PreviewNetplayScreen() { onStartGame = {}, onGameSelected = {}, gameFiles = emptyList(), + notAllPlayersHaveGame = emptyFlow(), + onConfirmStartGame = {}, hostInputAuthorityEnabled = true, networkMode = NetworkMode.HOST_INPUT_AUTHORITY, onNetworkModeChanged = {}, diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml index 6837e951fe..58bce8c595 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -997,6 +997,8 @@ It can efficiently compress both junk data and encrypted Wii data. <string name="netplay_port_label">Port</string> <string name="netplay_title">Netplay</string> <string name="netplay_start">Start</string> + <string name="netplay_start_warning_title">Warning</string> + <string name="netplay_start_warning_not_all_players_have_game">Not all players have the game. Do you really want to start?</string> <string name="netplay_chat_label">Chat</string> <string name="netplay_chat_send">Send</string> <string name="netplay_message_game_changed">Game changed to %1$s</string> |
