房间密码和房间人数调整
This commit is contained in:
parent
03c33d6371
commit
97ce9f9078
@ -44,10 +44,13 @@ namespace TH1_Logic.Net
|
||||
public void KickMember(ulong memberId);
|
||||
|
||||
// 创建房间
|
||||
public void CreateLobby(int maxMembers = 4,bool isPublic = true);
|
||||
public void CreateLobby(int maxMembers = 4,bool isPublic = true, string password = "");
|
||||
|
||||
// 加入房间
|
||||
public void JoinLobbyById(ulong lobbyId);
|
||||
public void JoinLobbyById(ulong lobbyId, string password = "");
|
||||
|
||||
// 通过邀请加入房间
|
||||
public void JoinLobbyByInvite(ulong lobbyId);
|
||||
|
||||
// 离开当前房间
|
||||
public void LeaveLobby();
|
||||
@ -67,6 +70,9 @@ namespace TH1_Logic.Net
|
||||
// 获取最大成员数
|
||||
public int GetMemberLimit();
|
||||
|
||||
// 设置最大成员数
|
||||
public bool SetMemberLimit(int maxMembers);
|
||||
|
||||
// 判断成员是否在房间中
|
||||
public bool IsMemberInLobby(ulong memberId);
|
||||
|
||||
@ -104,7 +110,12 @@ namespace TH1_Logic.Net
|
||||
|
||||
public class LobbyBase : ILobby
|
||||
{
|
||||
public void JoinLobbyById(ulong lobbyId)
|
||||
public void JoinLobbyById(ulong lobbyId, string password = "")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void JoinLobbyByInvite(ulong lobbyId)
|
||||
{
|
||||
|
||||
}
|
||||
@ -176,7 +187,7 @@ namespace TH1_Logic.Net
|
||||
return null;
|
||||
}
|
||||
|
||||
public void CreateLobby(int maxMembers = 4,bool isPublic = true)
|
||||
public void CreateLobby(int maxMembers = 4,bool isPublic = true, string password = "")
|
||||
{
|
||||
|
||||
}
|
||||
@ -193,6 +204,11 @@ namespace TH1_Logic.Net
|
||||
return 0;
|
||||
}
|
||||
|
||||
public bool SetMemberLimit(int maxMembers)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 判断成员是否在房间中
|
||||
public bool IsMemberInLobby(ulong memberId)
|
||||
{
|
||||
|
||||
@ -81,6 +81,14 @@ namespace TH1_Logic.Steam
|
||||
private int _suppressP2PSendFailureLobbyErrors;
|
||||
private const float SteamSessionCheckInterval = 1f;
|
||||
private const int SteamSessionFailThreshold = 2;
|
||||
private const string LobbyHasPasswordKey = "HasPassword";
|
||||
private const string LobbyPasswordKey = "Password";
|
||||
private const string LobbyIsPublicKey = "IsPublic";
|
||||
private string _pendingLobbyPassword = "";
|
||||
private bool _pendingLobbyIsPublic = true;
|
||||
private CSteamID _pendingJoinLobby = CSteamID.Nil;
|
||||
private string _pendingJoinPassword = "";
|
||||
private bool _pendingJoinCheckPassword = true;
|
||||
private string RoomName;
|
||||
|
||||
// 房间列表
|
||||
@ -124,6 +132,7 @@ namespace TH1_Logic.Steam
|
||||
private Callback<SteamServersDisconnected_t> _cbSteamServersDisconnected;
|
||||
private Callback<SteamServerConnectFailure_t> _cbSteamServerConnectFailure;
|
||||
private Callback<SteamShutdown_t> _cbSteamShutdown;
|
||||
private Callback<LobbyDataUpdate_t> _cbLobbyDataUpdate;
|
||||
|
||||
// 搜索公开房间
|
||||
private Callback<LobbyMatchList_t> _cbLobbyMatchList;
|
||||
@ -255,6 +264,7 @@ namespace TH1_Logic.Steam
|
||||
_cbSteamServersDisconnected = Callback<SteamServersDisconnected_t>.Create(OnSteamServersDisconnectedCallback);
|
||||
_cbSteamServerConnectFailure = Callback<SteamServerConnectFailure_t>.Create(OnSteamServerConnectFailureCallback);
|
||||
_cbSteamShutdown = Callback<SteamShutdown_t>.Create(OnSteamShutdownCallback);
|
||||
_cbLobbyDataUpdate = Callback<LobbyDataUpdate_t>.Create(OnLobbyDataUpdateCallback);
|
||||
|
||||
// 初始化P2P
|
||||
SimpleP2P.Instance.Initialize();
|
||||
@ -469,7 +479,7 @@ namespace TH1_Logic.Steam
|
||||
}
|
||||
|
||||
// 建房
|
||||
public void CreateLobby(int maxMembers = 4, bool isPublic = true)
|
||||
public void CreateLobby(int maxMembers = 4, bool isPublic = true, string password = "")
|
||||
{
|
||||
if (CurrentState != LobbyState.None)
|
||||
{
|
||||
@ -477,13 +487,20 @@ namespace TH1_Logic.Steam
|
||||
return;
|
||||
}
|
||||
|
||||
_pendingLobbyPassword = password ?? "";
|
||||
_pendingLobbyIsPublic = isPublic;
|
||||
CurrentState = LobbyState.Creating;
|
||||
LogSystem.LogInfo($"Creating public lobby with max members: {maxMembers}");
|
||||
LogSystem.LogInfo($"Creating {(isPublic ? "public" : "friends-only")} lobby with max members: {maxMembers}, hasPassword: {!string.IsNullOrEmpty(_pendingLobbyPassword)}");
|
||||
SteamMatchmaking.CreateLobby(isPublic?ELobbyType.k_ELobbyTypePublic:ELobbyType.k_ELobbyTypeFriendsOnly, maxMembers);
|
||||
}
|
||||
|
||||
// 加入房间
|
||||
public void JoinLobby(CSteamID lobbyId)
|
||||
public void JoinLobby(CSteamID lobbyId, string password = "")
|
||||
{
|
||||
JoinLobbyInternal(lobbyId, password, true, true);
|
||||
}
|
||||
|
||||
private void JoinLobbyInternal(CSteamID lobbyId, string password, bool requestLobbyDataIfMissing, bool checkPassword)
|
||||
{
|
||||
if (CurrentState != LobbyState.None)
|
||||
{
|
||||
@ -491,6 +508,25 @@ namespace TH1_Logic.Steam
|
||||
//return;
|
||||
}
|
||||
|
||||
if (requestLobbyDataIfMissing && ShouldRequestLobbyDataBeforeJoin(lobbyId))
|
||||
{
|
||||
_pendingJoinLobby = lobbyId;
|
||||
_pendingJoinPassword = password ?? "";
|
||||
_pendingJoinCheckPassword = checkPassword;
|
||||
|
||||
if (!SteamMatchmaking.RequestLobbyData(lobbyId))
|
||||
{
|
||||
ClearPendingJoinLobby();
|
||||
LogSystem.LogError($"Failed to request lobby data before joining: {lobbyId}");
|
||||
NetworkPlayerTipManager.Instance.Request(NetworkPlayerTipType.LobbyJoinFailed);
|
||||
OnLobbyErrorEvent?.Invoke("Failed to request lobby data before joining");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkPassword && !ValidateLobbyPasswordForJoin(lobbyId, password)) return;
|
||||
|
||||
// TODO 这里会涉及到房间子类对于UI的调用,对于房间的多态是不合理的,暂不处理,糊屎
|
||||
var version = SteamMatchmaking.GetLobbyData(lobbyId, "Version");
|
||||
if (!string.IsNullOrEmpty(version) && ConfigManager.Instance.VersionCfg.CurVersionInfo.Version != version)
|
||||
@ -573,10 +609,16 @@ namespace TH1_Logic.Steam
|
||||
}
|
||||
|
||||
// 通过房间ID直接加入(无需好友关系)
|
||||
public void JoinLobbyById(ulong lobbyId)
|
||||
public void JoinLobbyById(ulong lobbyId, string password = "")
|
||||
{
|
||||
var lobbyCSteamId = new CSteamID(lobbyId);
|
||||
JoinLobby(lobbyCSteamId);
|
||||
JoinLobby(lobbyCSteamId, password);
|
||||
}
|
||||
|
||||
public void JoinLobbyByInvite(ulong lobbyId)
|
||||
{
|
||||
var lobbyCSteamId = new CSteamID(lobbyId);
|
||||
JoinLobbyInternal(lobbyCSteamId, "", true, false);
|
||||
}
|
||||
|
||||
// 获取当前房间ID用于分享
|
||||
@ -595,7 +637,7 @@ namespace TH1_Logic.Steam
|
||||
}
|
||||
|
||||
// 通过房间码加入
|
||||
public void JoinByRoomCode(string code)
|
||||
public void JoinByRoomCode(string code, string password = "")
|
||||
{
|
||||
ulong lobbyId = Base36Decode(code);
|
||||
if (lobbyId == 0)
|
||||
@ -604,7 +646,68 @@ namespace TH1_Logic.Steam
|
||||
NetworkPlayerTipManager.Instance.Request(NetworkPlayerTipType.LobbyJoinFailed);
|
||||
return;
|
||||
}
|
||||
JoinLobbyById(lobbyId);
|
||||
JoinLobbyById(lobbyId, password);
|
||||
}
|
||||
|
||||
private bool ValidateLobbyPasswordForJoin(CSteamID lobbyId, string password)
|
||||
{
|
||||
if (!LobbyIsPublic(lobbyId)) return true;
|
||||
if (!LobbyHasPassword(lobbyId)) return true;
|
||||
|
||||
var expectedPassword = SteamMatchmaking.GetLobbyData(lobbyId, LobbyPasswordKey);
|
||||
if (!string.IsNullOrEmpty(expectedPassword) && (password ?? "") == expectedPassword) return true;
|
||||
|
||||
var errorMsg = string.IsNullOrEmpty(expectedPassword)
|
||||
? "Lobby password data is missing"
|
||||
: "Lobby password mismatch";
|
||||
LogSystem.LogInfo(errorMsg);
|
||||
NetworkPlayerTipManager.Instance.Request(NetworkPlayerTipType.LobbyJoinFailed);
|
||||
OnLobbyErrorEvent?.Invoke(errorMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool ShouldRequestLobbyDataBeforeJoin(CSteamID lobbyId)
|
||||
{
|
||||
if (!lobbyId.IsValid()) return false;
|
||||
if (!string.IsNullOrEmpty(SteamMatchmaking.GetLobbyData(lobbyId, "Game"))) return false;
|
||||
if (!string.IsNullOrEmpty(SteamMatchmaking.GetLobbyData(lobbyId, "Version"))) return false;
|
||||
if (!string.IsNullOrEmpty(SteamMatchmaking.GetLobbyData(lobbyId, LobbyHasPasswordKey))) return false;
|
||||
if (!string.IsNullOrEmpty(SteamMatchmaking.GetLobbyData(lobbyId, LobbyPasswordKey))) return false;
|
||||
if (!string.IsNullOrEmpty(SteamMatchmaking.GetLobbyData(lobbyId, LobbyIsPublicKey))) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ClearPendingJoinLobby()
|
||||
{
|
||||
_pendingJoinLobby = CSteamID.Nil;
|
||||
_pendingJoinPassword = "";
|
||||
_pendingJoinCheckPassword = true;
|
||||
}
|
||||
|
||||
private bool LobbyHasPassword(CSteamID lobbyId)
|
||||
{
|
||||
var hasPasswordData = SteamMatchmaking.GetLobbyData(lobbyId, LobbyHasPasswordKey);
|
||||
if (IsTrueLobbyData(hasPasswordData)) return true;
|
||||
if (IsFalseLobbyData(hasPasswordData)) return false;
|
||||
return !string.IsNullOrEmpty(SteamMatchmaking.GetLobbyData(lobbyId, LobbyPasswordKey));
|
||||
}
|
||||
|
||||
private bool LobbyIsPublic(CSteamID lobbyId)
|
||||
{
|
||||
var isPublicData = SteamMatchmaking.GetLobbyData(lobbyId, LobbyIsPublicKey);
|
||||
if (IsTrueLobbyData(isPublicData)) return true;
|
||||
if (IsFalseLobbyData(isPublicData)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool IsTrueLobbyData(string value)
|
||||
{
|
||||
return value == "1" || string.Equals(value, "true", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private static bool IsFalseLobbyData(string value)
|
||||
{
|
||||
return value == "0" || string.Equals(value, "false", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
private string Base36Encode(ulong value)
|
||||
@ -730,6 +833,7 @@ namespace TH1_Logic.Steam
|
||||
Version = SteamMatchmaking.GetLobbyData(CurrentLobby, "Version"),
|
||||
CurrentPlayers = SteamMatchmaking.GetNumLobbyMembers(CurrentLobby),
|
||||
MaxPlayers = SteamMatchmaking.GetLobbyMemberLimit(CurrentLobby),
|
||||
HasPassword = LobbyHasPassword(CurrentLobby),
|
||||
};
|
||||
var data = new InviteMessage();
|
||||
data.LobbyInfo = lobbyInfo;
|
||||
@ -801,6 +905,7 @@ namespace TH1_Logic.Steam
|
||||
CurrentPlayers = SteamMatchmaking.GetNumLobbyMembers(lobbyId),
|
||||
MaxPlayers = SteamMatchmaking.GetLobbyMemberLimit(lobbyId),
|
||||
GameState = int.Parse(SteamMatchmaking.GetLobbyData(lobbyId, "GameState")),
|
||||
HasPassword = LobbyHasPassword(lobbyId),
|
||||
});
|
||||
}
|
||||
|
||||
@ -820,6 +925,7 @@ namespace TH1_Logic.Steam
|
||||
lobbyInfo.CurrentPlayers = SteamMatchmaking.GetNumLobbyMembers(cSteamId);
|
||||
lobbyInfo.MaxPlayers = SteamMatchmaking.GetLobbyMemberLimit(cSteamId);
|
||||
lobbyInfo.GameState = int.Parse(SteamMatchmaking.GetLobbyData(cSteamId, "GameState"));
|
||||
lobbyInfo.HasPassword = LobbyHasPassword(cSteamId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -947,6 +1053,8 @@ namespace TH1_Logic.Steam
|
||||
if (data.m_eResult != EResult.k_EResultOK)
|
||||
{
|
||||
CurrentState = LobbyState.None;
|
||||
_pendingLobbyPassword = "";
|
||||
_pendingLobbyIsPublic = true;
|
||||
LogSystem.LogError($"Failed to create lobby: {data.m_eResult}");
|
||||
NetworkPlayerTipManager.Instance.Request(NetworkPlayerTipType.LobbyCreateFailed);
|
||||
return;
|
||||
@ -965,6 +1073,11 @@ namespace TH1_Logic.Steam
|
||||
SteamMatchmaking.SetLobbyData(CurrentLobby, "RoomName", SelfName + MultilingualManager.Instance.GetMultilingualText(Table.Instance.TextDataAssets.OutsideMultiplayRoomNameSuffix));
|
||||
SteamMatchmaking.SetLobbyData(CurrentLobby, "RoomCode", GenerateRoomCode());
|
||||
SteamMatchmaking.SetLobbyData(CurrentLobby, "GameState", "0");
|
||||
SteamMatchmaking.SetLobbyData(CurrentLobby, LobbyHasPasswordKey, string.IsNullOrEmpty(_pendingLobbyPassword) ? "false" : "true");
|
||||
SteamMatchmaking.SetLobbyData(CurrentLobby, LobbyPasswordKey, _pendingLobbyPassword);
|
||||
SteamMatchmaking.SetLobbyData(CurrentLobby, LobbyIsPublicKey, _pendingLobbyIsPublic ? "true" : "false");
|
||||
_pendingLobbyPassword = "";
|
||||
_pendingLobbyIsPublic = true;
|
||||
|
||||
// 设置Rich Presence
|
||||
SteamFriends.SetRichPresence("status", "In Lobby");
|
||||
@ -1000,6 +1113,26 @@ namespace TH1_Logic.Steam
|
||||
HandleLocalSteamSessionLost("Steam shutdown callback");
|
||||
}
|
||||
|
||||
private void OnLobbyDataUpdateCallback(LobbyDataUpdate_t data)
|
||||
{
|
||||
var lobbyId = new CSteamID(data.m_ulSteamIDLobby);
|
||||
if (!_pendingJoinLobby.IsValid() || lobbyId != _pendingJoinLobby) return;
|
||||
|
||||
var password = _pendingJoinPassword;
|
||||
var checkPassword = _pendingJoinCheckPassword;
|
||||
ClearPendingJoinLobby();
|
||||
|
||||
if (data.m_bSuccess == 0)
|
||||
{
|
||||
LogSystem.LogError($"Failed to refresh lobby data before joining: {lobbyId}");
|
||||
NetworkPlayerTipManager.Instance.Request(NetworkPlayerTipType.LobbyJoinFailed);
|
||||
OnLobbyErrorEvent?.Invoke("Failed to refresh lobby data before joining");
|
||||
return;
|
||||
}
|
||||
|
||||
JoinLobbyInternal(lobbyId, password, false, checkPassword);
|
||||
}
|
||||
|
||||
// 加入请求回调
|
||||
private void OnLobbyJoinRequestedCallback(GameLobbyJoinRequested_t data)
|
||||
{
|
||||
@ -1014,7 +1147,7 @@ namespace TH1_Logic.Steam
|
||||
return;
|
||||
}
|
||||
|
||||
JoinLobby(data.m_steamIDLobby);
|
||||
JoinLobbyInternal(data.m_steamIDLobby, "", true, false);
|
||||
}
|
||||
|
||||
// 进入房间回调
|
||||
@ -1173,6 +1306,9 @@ namespace TH1_Logic.Steam
|
||||
_isHandlingSessionLoss = false;
|
||||
_steamSessionFailCount = 0;
|
||||
_refreshSteamStatus = 0f;
|
||||
_pendingLobbyPassword = "";
|
||||
_pendingLobbyIsPublic = true;
|
||||
ClearPendingJoinLobby();
|
||||
|
||||
// 清除Rich Presence
|
||||
SteamFriends.ClearRichPresence();
|
||||
@ -1421,6 +1557,53 @@ namespace TH1_Logic.Steam
|
||||
if (!CurrentLobby.IsValid()) return 0;
|
||||
return SteamMatchmaking.GetLobbyMemberLimit(CurrentLobby);
|
||||
}
|
||||
|
||||
// 设置最大成员数
|
||||
public bool SetMemberLimit(int maxMembers)
|
||||
{
|
||||
if (!IsLobbyOwner())
|
||||
{
|
||||
LogSystem.LogError("Only lobby owner can change lobby member limit");
|
||||
NetworkPlayerTipManager.Instance.Request(NetworkPlayerTipType.LobbyOperationFailed);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CurrentLobby.IsValid())
|
||||
{
|
||||
LogSystem.LogError("Not in a lobby");
|
||||
NetworkPlayerTipManager.Instance.Request(NetworkPlayerTipType.LobbyOperationFailed);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (maxMembers <= 0)
|
||||
{
|
||||
LogSystem.LogError($"Invalid lobby member limit: {maxMembers}");
|
||||
NetworkPlayerTipManager.Instance.Request(NetworkPlayerTipType.LobbyOperationFailed);
|
||||
return false;
|
||||
}
|
||||
|
||||
int memberCount = GetMemberCount();
|
||||
if (maxMembers < memberCount)
|
||||
{
|
||||
LogSystem.LogError($"Cannot set lobby member limit below current member count: limit={maxMembers}, current={memberCount}");
|
||||
NetworkPlayerTipManager.Instance.Request(NetworkPlayerTipType.LobbyOperationFailed);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = SteamMatchmaking.SetLobbyMemberLimit(CurrentLobby, maxMembers);
|
||||
if (success)
|
||||
{
|
||||
LogSystem.LogInfo($"Lobby member limit changed to: {maxMembers}");
|
||||
EventManager.Publish(new UpdateUIOutsideMultiplayLobbyList());
|
||||
}
|
||||
else
|
||||
{
|
||||
LogSystem.LogError($"Failed to change lobby member limit to: {maxMembers}");
|
||||
NetworkPlayerTipManager.Instance.Request(NetworkPlayerTipType.LobbyOperationFailed);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// 判断成员是否在房间中
|
||||
public bool IsMemberInLobby(ulong memberId)
|
||||
@ -1510,6 +1693,7 @@ namespace TH1_Logic.Steam
|
||||
_cbSteamServersDisconnected?.Dispose();
|
||||
_cbSteamServerConnectFailure?.Dispose();
|
||||
_cbSteamShutdown?.Dispose();
|
||||
_cbLobbyDataUpdate?.Dispose();
|
||||
|
||||
LogSystem.LogInfo("SteamLobbyManager cleaned up");
|
||||
}
|
||||
@ -1529,5 +1713,6 @@ namespace TH1_Logic.Steam
|
||||
public int CurrentPlayers;
|
||||
public int MaxPlayers;
|
||||
public int GameState;
|
||||
public bool HasPassword;
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,8 +87,8 @@ namespace TH1_UI.Controller.Outside
|
||||
void _OnBtnCheckClick()
|
||||
{
|
||||
//Step #1 加入对方lobby
|
||||
LobbyManager.Instance.Lobby?.JoinLobbyById(_lobbyId);
|
||||
LobbyManager.Instance.Lobby?.JoinLobbyByInvite(_lobbyId);
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,9 +95,9 @@ namespace TH1_UI.Controller.Top
|
||||
Main.Instance.GameLogic.ChangeState(GameState.Menu);
|
||||
|
||||
//Step #2 加入对方lobby
|
||||
LobbyManager.Instance.Lobby?.JoinLobbyById(_lobbyId);
|
||||
LobbyManager.Instance.Lobby?.JoinLobbyByInvite(_lobbyId);
|
||||
//Step #3 关闭画面
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user