117 lines
4.4 KiB
C#
117 lines
4.4 KiB
C#
using System;
|
|
using Steamworks;
|
|
using UnityEngine;
|
|
|
|
namespace MegaKoop.Game.Networking
|
|
{
|
|
/// <summary>
|
|
/// Wraps Steam lobby creation and join logic for cooperative sessions.
|
|
/// </summary>
|
|
[DisallowMultipleComponent]
|
|
public class SteamLobbyManager : MonoBehaviour
|
|
{
|
|
[SerializeField] private int maxPlayers = 4;
|
|
|
|
public event Action<LobbyDataUpdate_t> LobbyDataUpdated;
|
|
public event Action<CSteamID> LobbyCreated;
|
|
public event Action<CSteamID> LobbyJoined;
|
|
public event Action<CSteamID> LobbyMemberJoined;
|
|
public event Action<CSteamID> LobbyMemberLeft;
|
|
|
|
private Callback<LobbyCreated_t> lobbyCreatedCallback;
|
|
private Callback<LobbyEnter_t> lobbyEnterCallback;
|
|
private Callback<LobbyDataUpdate_t> lobbyDataUpdateCallback;
|
|
private Callback<LobbyChatUpdate_t> lobbyChatUpdateCallback;
|
|
|
|
private CSteamID activeLobbyId;
|
|
|
|
private void OnEnable()
|
|
{
|
|
lobbyCreatedCallback = Callback<LobbyCreated_t>.Create(OnLobbyCreated);
|
|
lobbyEnterCallback = Callback<LobbyEnter_t>.Create(OnLobbyEntered);
|
|
lobbyDataUpdateCallback = Callback<LobbyDataUpdate_t>.Create(OnLobbyDataUpdated);
|
|
lobbyChatUpdateCallback = Callback<LobbyChatUpdate_t>.Create(OnLobbyChatUpdate);
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
lobbyCreatedCallback?.Dispose();
|
|
lobbyEnterCallback?.Dispose();
|
|
lobbyDataUpdateCallback?.Dispose();
|
|
lobbyChatUpdateCallback?.Dispose();
|
|
}
|
|
|
|
public void HostLobby(string lobbyName)
|
|
{
|
|
if (!SteamBootstrap.IsInitialized || !SteamAPI.IsSteamRunning())
|
|
{
|
|
Debug.LogWarning("[SteamLobbyManager] Steam is not initialized; cannot create lobby.");
|
|
return;
|
|
}
|
|
|
|
SteamMatchmaking.CreateLobby(ELobbyType.k_ELobbyTypePublic, Mathf.Max(2, maxPlayers));
|
|
pendingLobbyName = lobbyName;
|
|
}
|
|
|
|
public void JoinLobby(CSteamID lobbyId)
|
|
{
|
|
if (!SteamBootstrap.IsInitialized || !SteamAPI.IsSteamRunning())
|
|
{
|
|
Debug.LogWarning("[SteamLobbyManager] Steam not running; cannot join lobby.");
|
|
return;
|
|
}
|
|
|
|
SteamMatchmaking.JoinLobby(lobbyId);
|
|
}
|
|
|
|
public CSteamID GetActiveLobby() => activeLobbyId;
|
|
|
|
private string pendingLobbyName;
|
|
|
|
private void OnLobbyCreated(LobbyCreated_t callback)
|
|
{
|
|
if (callback.m_eResult != EResult.k_EResultOK)
|
|
{
|
|
Debug.LogError("[SteamLobbyManager] Lobby creation failed: " + callback.m_eResult);
|
|
return;
|
|
}
|
|
|
|
activeLobbyId = new CSteamID(callback.m_ulSteamIDLobby);
|
|
SteamMatchmaking.SetLobbyData(activeLobbyId, "name", string.IsNullOrEmpty(pendingLobbyName) ? "MegaKoop Lobby" : pendingLobbyName);
|
|
SteamMatchmaking.SetLobbyData(activeLobbyId, "owner", SteamUser.GetSteamID().ToString());
|
|
LobbyCreated?.Invoke(activeLobbyId);
|
|
Debug.Log("[SteamLobbyManager] Lobby created " + activeLobbyId);
|
|
}
|
|
|
|
private void OnLobbyEntered(LobbyEnter_t callback)
|
|
{
|
|
activeLobbyId = new CSteamID(callback.m_ulSteamIDLobby);
|
|
LobbyJoined?.Invoke(activeLobbyId);
|
|
Debug.Log("[SteamLobbyManager] Entered lobby " + activeLobbyId);
|
|
}
|
|
|
|
private void OnLobbyDataUpdated(LobbyDataUpdate_t callback)
|
|
{
|
|
LobbyDataUpdated?.Invoke(callback);
|
|
}
|
|
|
|
private void OnLobbyChatUpdate(LobbyChatUpdate_t callback)
|
|
{
|
|
CSteamID lobby = new CSteamID(callback.m_ulSteamIDLobby);
|
|
CSteamID changedUser = new CSteamID(callback.m_ulSteamIDUserChanged);
|
|
|
|
EChatMemberStateChange stateChange = (EChatMemberStateChange)callback.m_rgfChatMemberStateChange;
|
|
|
|
if ((stateChange & EChatMemberStateChange.k_EChatMemberStateChangeEntered) != 0)
|
|
{
|
|
LobbyMemberJoined?.Invoke(changedUser);
|
|
}
|
|
|
|
if ((stateChange & (EChatMemberStateChange.k_EChatMemberStateChangeLeft | EChatMemberStateChange.k_EChatMemberStateChangeDisconnected | EChatMemberStateChange.k_EChatMemberStateChangeKicked | EChatMemberStateChange.k_EChatMemberStateChangeBanned)) != 0)
|
|
{
|
|
LobbyMemberLeft?.Invoke(changedUser);
|
|
}
|
|
}
|
|
}
|
|
}
|