TH1/Unity/Assets/Scripts/TH1_UI/View/Bottom/UIBottomNetRowMono.cs

319 lines
11 KiB
C#

using Logic.Multilingual;
using RuntimeData;
using TH1_Core.Managers;
using TH1_Logic.Core;
using TH1_Logic.Net;
using TH1_Logic.Steam;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace TH1_UI.View.Bottom
{
public class UIBottomNetRowMono : MonoBehaviour
{
public TextMeshProUGUI Name;
public TextMeshProUGUI Prop;
public TextMeshProUGUI Status;
public Image NetworkImage;
public Sprite Network_0;
public Sprite Network_1;
public Sprite Network_2;
public Sprite Network_3;
public Button InviteButton;
public TextMeshProUGUI InviteButtonText;
public Image InviteButtonImage;
public Sprite InviteButtonBG;
public Sprite AlreadyInvitedButtonBG;
public Button AIButton;
public Button CancelAIButton;
public GameObject AIPlayHint;
private ulong _memberid;
private bool _isNetOk;
private bool _isRoomOwner;
private bool _invited;
public ulong MemberId => _memberid;
private void SetNoInvite()
{
_invited = false;
if (InviteButton != null) InviteButton.gameObject.SetActive(false);
}
private void SetInvite()
{
_invited = false;
if (InviteButton == null) return;
InviteButton.gameObject.SetActive(true);
InviteButtonText.text = MultilingualManager.Instance.GetMultilingualText(Table.Instance.TextDataAssets.MultiplayInviteButton);
InviteButtonImage.sprite = InviteButtonBG;
}
private void SetAlreadyInvited()
{
_invited = true;
if (InviteButton == null) return;
InviteButton.gameObject.SetActive(true);
InviteButtonText.text = MultilingualManager.Instance.GetMultilingualText(Table.Instance.TextDataAssets.MultiplayAlreadyInvitedButton);
InviteButtonImage.sprite = AlreadyInvitedButtonBG;
}
public void InitContent(ulong memberid, MemberInfo memberInfo, bool isRoomOwner, bool isNetOk)
{
_memberid = memberid;
_isNetOk = isNetOk;
_isRoomOwner = isRoomOwner;
if (memberInfo != null) Name.text = memberInfo.Name;
MultilingualManager.Instance.SetUIText(Prop, isRoomOwner ? Table.Instance.TextDataAssets.MultiplayRoomOwnerTitle : Table.Instance.TextDataAssets.MultiplayRoomGuestTitle);
UpdatePingStatus(isNetOk);
UpdateOfflineActions(isNetOk);
}
public void InitContent(MemberCiv slot, MemberInfo memberInfo, bool isRoomOwner, ulong ownerMemberId)
{
_memberid = slot?.MemberId ?? 0;
_isRoomOwner = isRoomOwner;
_isNetOk = _memberid != 0 && IsMemberOnline(_memberid);
if (_memberid == 0)
{
Name.text = string.Empty;
Prop.text = string.Empty;
Status.text = string.Empty;
SetNetworkSprite(0);
SetNoInvite();
SetNoAIControls();
return;
}
if (memberInfo != null) Name.text = memberInfo.Name;
MultilingualManager.Instance.SetUIText(Prop, _memberid == ownerMemberId ? Table.Instance.TextDataAssets.MultiplayRoomOwnerTitle : Table.Instance.TextDataAssets.MultiplayRoomGuestTitle);
UpdatePingStatus(_isNetOk);
UpdateOfflineActions(_isNetOk);
}
public void UpdateNetStatus(bool isRoomOwner, bool isNetOk)
{
_isNetOk = isNetOk;
_isRoomOwner = isRoomOwner;
MultilingualManager.Instance.SetUIText(Prop, isRoomOwner ? Table.Instance.TextDataAssets.MultiplayRoomOwnerTitle : Table.Instance.TextDataAssets.MultiplayRoomGuestTitle);
UpdatePingStatus(isNetOk);
UpdateOfflineActions(isNetOk);
}
private void UpdateOfflineActions(bool isNetOk)
{
if (_memberid == 0)
{
SetNoInvite();
SetNoAIControls();
return;
}
var confirm = Main.Instance?.ConfirmMap?.GetPlayerConfirm(_memberid);
if (isNetOk)
{
if (confirm != null && confirm.AIControl && IsSelfRoomOwner())
{
confirm.AIControl = false;
GameNetSender.Instance.SendMemberStateSync();
}
SetNoInvite();
SetNoAIControls();
return;
}
var aiControlled = confirm != null && confirm.AIControl;
SetAIPlayHint(aiControlled);
if (aiControlled)
{
SetNoInvite();
SetAIButtonActive(false);
SetCancelAIButtonActive(IsSelfRoomOwner());
BindCancelAIButton(confirm);
return;
}
SetCancelAIButtonActive(false);
if (!IsSelfRoomOwner())
{
SetNoInvite();
SetAIButtonActive(false);
return;
}
if (!_invited) SetInvite();
BindInviteButton();
SetAIButtonActive(true);
BindAIButton(confirm);
}
private void SetNoAIControls()
{
SetAIButtonActive(false);
SetCancelAIButtonActive(false);
SetAIPlayHint(false);
}
private void SetAIButtonActive(bool active)
{
if (AIButton != null) AIButton.gameObject.SetActive(active);
}
private void SetCancelAIButtonActive(bool active)
{
if (CancelAIButton != null) CancelAIButton.gameObject.SetActive(active);
}
private void SetAIPlayHint(bool active)
{
if (AIPlayHint != null) AIPlayHint.SetActive(active);
}
private void BindInviteButton()
{
if (InviteButton == null) return;
InviteButton.onClick.RemoveAllListeners();
InviteButton.onClick.AddListener(() =>
{
var lobby = LobbyManager.Instance.Lobby as SteamLobbyManager;
if (lobby == null) return;
lobby.InviteFriend(_memberid);
InviteButton.gameObject.SetActive(false);
if (_invited) return;
Timer.Instance.TimerRegister(this, () =>
{
if (ShouldShowInvite()) SetInvite();
}, 3f, "UIBottomNetRowMono_InviteClick");
SetAlreadyInvited();
});
}
private void BindAIButton(PlayerConfirmData confirm)
{
if (AIButton == null) return;
AIButton.onClick.RemoveAllListeners();
AIButton.onClick.AddListener(() =>
{
var data = confirm ?? Main.Instance?.ConfirmMap?.GetPlayerConfirm(_memberid);
if (data == null) return;
if (data.State == MemberNetState.OK) data.State = ResolveOfflineState();
data.AIControl = true;
SetNoInvite();
SetAIPlayHint(true);
SetAIButtonActive(false);
SetCancelAIButtonActive(true);
BindCancelAIButton(data);
GameNetSender.Instance.SendMemberStateSync();
});
}
private void BindCancelAIButton(PlayerConfirmData confirm)
{
if (CancelAIButton == null) return;
CancelAIButton.onClick.RemoveAllListeners();
CancelAIButton.onClick.AddListener(() =>
{
var data = confirm ?? Main.Instance?.ConfirmMap?.GetPlayerConfirm(_memberid);
if (data == null) return;
data.AIControl = false;
SetAIPlayHint(false);
SetCancelAIButtonActive(false);
SetAIButtonActive(true);
SetInvite();
BindInviteButton();
BindAIButton(data);
GameNetSender.Instance.SendMemberStateSync();
});
}
private bool ShouldShowInvite()
{
if (_isNetOk) return false;
if (!IsSelfRoomOwner()) return false;
var confirm = Main.Instance?.ConfirmMap?.GetPlayerConfirm(_memberid);
return confirm == null || !confirm.AIControl;
}
private bool IsSelfRoomOwner()
{
return LobbyManager.Instance.Lobby != null && LobbyManager.Instance.Lobby.IsLobbyOwner();
}
private void UpdatePingStatus(bool isNetOk)
{
var confirm = Main.Instance?.ConfirmMap?.GetPlayerConfirm(_memberid);
if (confirm == null)
{
Status.text = "-- ms";
SetNetworkSprite(0);
return;
}
if (!isNetOk)
{
Status.text = GetOfflineStatusText(confirm.State);
SetNetworkSprite(0);
return;
}
var pingMs = Mathf.RoundToInt(confirm.GetPing() * 1000f);
Status.text = $"{pingMs} ms";
SetNetworkSprite(GetNetworkLevel(pingMs));
}
private string GetOfflineStatusText(MemberNetState state)
{
return MultilingualManager.Instance.GetMultilingualText(Table.Instance.TextDataAssets.MultiplayNetDisconnectTitle);
}
private MemberNetState ResolveOfflineState()
{
var lobby = LobbyManager.Instance.Lobby;
return lobby != null && lobby.IsInLobby() && lobby.IsMemberInLobby(_memberid)
? MemberNetState.Disconnected
: MemberNetState.Leaved;
}
private bool IsMemberOnline(ulong memberId)
{
if (memberId == 0) return false;
var lobby = LobbyManager.Instance.Lobby;
if (lobby == null || !lobby.IsInLobby()) return false;
if (!lobby.IsMemberInLobby(memberId)) return false;
var confirm = Main.Instance?.ConfirmMap?.GetPlayerConfirm(memberId);
return confirm == null || confirm.State == MemberNetState.OK;
}
private int GetNetworkLevel(int pingMs)
{
if (pingMs < 0) return 0;
if (pingMs < 100) return 3;
if (pingMs < 200) return 2;
if (pingMs < 500) return 1;
return 0;
}
private void SetNetworkSprite(int level)
{
if (NetworkImage == null) return;
NetworkImage.sprite = level switch
{
3 => Network_3,
2 => Network_2,
1 => Network_1,
_ => Network_0
};
}
}
}