mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-05-09 04:13:28 -05:00
Handle desync messages
Show them in the chat window and also in a toast during game play.
This commit is contained in:
parent
1285cb2282
commit
8792a4b924
|
|
@ -95,6 +95,12 @@ class NetplaySession(
|
|||
)
|
||||
val padBuffer = _padBuffer.asSharedFlow()
|
||||
|
||||
private val _desyncMessages = MutableSharedFlow<NetplayMessage.Desync>(
|
||||
extraBufferCapacity = 32,
|
||||
onBufferOverflow = BufferOverflow.DROP_OLDEST
|
||||
)
|
||||
val desyncMessages = _desyncMessages.asSharedFlow()
|
||||
|
||||
private val _saveTransferProgress = MutableStateFlow<SaveTransferProgress?>(null)
|
||||
val saveTransferProgress = _saveTransferProgress.asStateFlow()
|
||||
|
||||
|
|
@ -146,6 +152,7 @@ class NetplaySession(
|
|||
game.map { NetplayMessage.GameChanged(it) },
|
||||
hostInputAuthorityEnabled.map { NetplayMessage.HostInputAuthorityChanged(it) },
|
||||
padBuffer.map { NetplayMessage.BufferChanged(it) },
|
||||
desyncMessages,
|
||||
)
|
||||
|
||||
private fun releaseNativeResources() {
|
||||
|
|
@ -234,6 +241,11 @@ class NetplaySession(
|
|||
_padBuffer.tryEmit(buffer)
|
||||
}
|
||||
|
||||
@Keep
|
||||
fun onDesync(frame: Int, player: String) {
|
||||
_desyncMessages.tryEmit(NetplayMessage.Desync(player, frame))
|
||||
}
|
||||
|
||||
@Keep
|
||||
fun onShowChunkedProgressDialog(title: String, dataSize: Long, playerIds: IntArray) {
|
||||
val players = _players.replayCache.firstOrNull()
|
||||
|
|
|
|||
|
|
@ -26,4 +26,9 @@ sealed class NetplayMessage {
|
|||
override fun message(context: Context) =
|
||||
context.getString(R.string.netplay_message_buffer_changed, buffer)
|
||||
}
|
||||
|
||||
class Desync(private val player: String, private val frame: Int) : NetplayMessage() {
|
||||
override fun message(context: Context) =
|
||||
context.getString(R.string.netplay_message_desync, player, frame)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,12 @@ import android.view.LayoutInflater
|
|||
import android.view.SurfaceHolder
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary
|
||||
import org.dolphinemu.dolphinemu.activities.EmulationActivity
|
||||
|
|
@ -231,6 +234,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
netplaySession.stopGame.first()
|
||||
stopEmulation()
|
||||
}
|
||||
netplaySession
|
||||
.desyncMessages
|
||||
.onEach { Toast.makeText(requireContext(), it.message(requireContext()), Toast.LENGTH_SHORT).show() }
|
||||
.launchIn(lifecycleScope)
|
||||
NativeLibrary.RunNetPlay(
|
||||
paths,
|
||||
riivolution,
|
||||
|
|
|
|||
|
|
@ -1002,6 +1002,7 @@ It can efficiently compress both junk data and encrypted Wii data.
|
|||
<string name="netplay_message_game_changed">Game changed to %1$s</string>
|
||||
<string name="netplay_message_buffer_changed">Buffer size changed to %1$d</string>
|
||||
<string name="netplay_message_host_input_authority_changed">"Host input authority %1$s"</string>
|
||||
<string name="netplay_message_desync">Possible desync detected: %1$s might have desynced at frame %2$d</string>
|
||||
<string name="netplay_game_label">Game</string>
|
||||
<string name="netplay_players_label">Players</string>
|
||||
<string name="netplay_players_name">Name</string>
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ static jmethodID s_netplay_update;
|
|||
static jmethodID s_netplay_on_show_chunked_progress_dialog;
|
||||
static jmethodID s_netplay_on_set_chunked_progress;
|
||||
static jmethodID s_netplay_on_hide_chunked_progress_dialog;
|
||||
static jmethodID s_netplay_on_desync;
|
||||
|
||||
static jclass s_netplay_player_class;
|
||||
static jmethodID s_netplay_player_constructor;
|
||||
|
|
@ -327,6 +328,11 @@ jmethodID GetNetplayOnHideChunkedProgressDialog()
|
|||
return s_netplay_on_hide_chunked_progress_dialog;
|
||||
}
|
||||
|
||||
jmethodID GetNetplayOnDesync()
|
||||
{
|
||||
return s_netplay_on_desync;
|
||||
}
|
||||
|
||||
jclass GetNetplayPlayerClass()
|
||||
{
|
||||
return s_netplay_player_class;
|
||||
|
|
@ -766,6 +772,8 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
|||
env->GetMethodID(netplay_class, "onSetChunkedProgress", "(IJ)V");
|
||||
s_netplay_on_hide_chunked_progress_dialog =
|
||||
env->GetMethodID(netplay_class, "onHideChunkedProgressDialog", "()V");
|
||||
s_netplay_on_desync =
|
||||
env->GetMethodID(netplay_class, "onDesync", "(ILjava/lang/String;)V");
|
||||
env->DeleteLocalRef(netplay_class);
|
||||
|
||||
const jclass netplay_player_class =
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ jmethodID GetNetplayUpdate();
|
|||
jmethodID GetNetplayOnShowChunkedProgressDialog();
|
||||
jmethodID GetNetplayOnSetChunkedProgress();
|
||||
jmethodID GetNetplayOnHideChunkedProgressDialog();
|
||||
jmethodID GetNetplayOnDesync();
|
||||
|
||||
jclass GetNetplayPlayerClass();
|
||||
jmethodID GetNetplayPlayerConstructor();
|
||||
|
|
|
|||
|
|
@ -197,7 +197,17 @@ void NetPlayUICallbacks::OnHostInputAuthorityChanged(bool enabled)
|
|||
env->DeleteLocalRef(netplay_session);
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::OnDesync(u32, const std::string&) {}
|
||||
void NetPlayUICallbacks::OnDesync(u32 frame, const std::string& player)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnDesync(),
|
||||
static_cast<jint>(frame), ToJString(env, player));
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::OnConnectionLost()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user