Implement DoAllPlayersHaveGame() check

This commit is contained in:
Tom Pratt 2026-05-06 11:49:31 +02:00
parent c0e44478a0
commit 37e34af96a
6 changed files with 61 additions and 1 deletions

View File

@ -166,6 +166,8 @@ class NetplaySession(
fun changeGame(gameFile: GameFile) = nativeChangeGame(gameFile)
fun doAllPlayersHaveGame(): Boolean = nativeDoAllPlayersHaveGame()
fun startGame() = nativeStartGame()
fun getPort(): Int = nativeGetPort()
@ -257,6 +259,8 @@ class NetplaySession(
private external fun nativeChangeGame(gameFile: GameFile)
private external fun nativeDoAllPlayersHaveGame(): Boolean
private external fun nativeStartGame()
private external fun nativeGetPort(): Int

View File

@ -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 _startGameWarning = Channel<Unit>(Channel.CONFLATED)
val startGameWarning = _startGameWarning.receiveAsFlow()
fun startGame() {
if (netplaySession.doAllPlayersHaveGame()) {
netplaySession.startGame()
} else {
_startGameWarning.trySend(Unit)
}
}
fun confirmStartGame() {
netplaySession.startGame()
}

View File

@ -49,15 +49,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,
startGameWarning = viewModel.startGameWarning,
onConfirmStartGame = viewModel::confirmStartGame,
players = viewModel.players.collectAsState().value,
hostInputAuthorityEnabled = viewModel.hostInputAuthority.collectAsState().value,
networkMode = viewModel.networkMode.collectAsState().value,

View File

@ -121,6 +121,8 @@ fun NetplayScreen(
onStartGame: () -> Unit,
onGameSelected: (GameFile) -> Unit,
gameFiles: List<GameFile>,
startGameWarning: Flow<Unit>,
onConfirmStartGame: () -> Unit,
hostInputAuthorityEnabled: Boolean,
networkMode: NetworkMode,
onNetworkModeChanged: (NetworkMode) -> Unit,
@ -229,6 +231,11 @@ fun NetplayScreen(
fatalTraversalError.collect { traversalError = it }
}
var showStartGameWarning by rememberSaveable { mutableStateOf(false) }
LaunchedEffect(Unit) {
startGameWarning.collect { showStartGameWarning = true }
}
var dismissSaveTransferProgressDialog by rememberSaveable { mutableStateOf(false) }
if (saveTransferProgress == null) {
dismissSaveTransferProgressDialog = false
@ -279,6 +286,27 @@ fun NetplayScreen(
onDismiss = { dismissGameDigestDialog = true },
)
}
showStartGameWarning -> {
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 = {
showStartGameWarning = false
onConfirmStartGame()
}) {
Text(stringResource(R.string.yes))
}
},
dismissButton = {
TextButton(onClick = { showStartGameWarning = false }) {
Text(stringResource(R.string.no))
}
},
onDismissRequest = { showStartGameWarning = false },
)
}
}
}
}
@ -1280,6 +1308,8 @@ private fun PreviewNetplayScreen() {
onStartGame = {},
onGameSelected = {},
gameFiles = emptyList(),
startGameWarning = emptyFlow(),
onConfirmStartGame = {},
hostInputAuthorityEnabled = true,
networkMode = NetworkMode.HOST_INPUT_AUTHORITY,
onNetworkModeChanged = {},

View File

@ -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>

View File

@ -181,6 +181,15 @@ Java_org_dolphinemu_dolphinemu_features_netplay_NetplaySession_nativeChangeGame(
server->ChangeGame(game_file->GetSyncIdentifier(), game_file->GetLongName());
}
JNIEXPORT jboolean JNICALL
Java_org_dolphinemu_dolphinemu_features_netplay_NetplaySession_nativeDoAllPlayersHaveGame(
JNIEnv* env, jobject obj)
{
if (auto* client = GetClientPointer(env, obj))
return static_cast<jboolean>(client->DoAllPlayersHaveGame());
return JNI_TRUE;
}
JNIEXPORT void JNICALL
Java_org_dolphinemu_dolphinemu_features_netplay_NetplaySession_nativeStartGame(JNIEnv* env,
jobject obj)