337 lines
11 KiB
C#
337 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 _isAISlot;
|
|
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;
|
|
_isAISlot = false;
|
|
|
|
Name.text = memberInfo?.Name ?? GetFallbackHumanName(memberid);
|
|
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)
|
|
{
|
|
_memberid = slot?.MemberId ?? 0;
|
|
_isRoomOwner = isRoomOwner;
|
|
_isAISlot = slot != null && slot.MemberId == 0 && slot.IsAI;
|
|
_isNetOk = _memberid != 0 && IsMemberOnline(_memberid);
|
|
|
|
if (_isAISlot)
|
|
{
|
|
Name.text = GetAIPlayerName(slot);
|
|
Prop.text = "AI";
|
|
UpdateAIStatus();
|
|
return;
|
|
}
|
|
|
|
Name.text = memberInfo?.Name ?? GetFallbackHumanName(_memberid);
|
|
MultilingualManager.Instance.SetUIText(Prop, isRoomOwner ? Table.Instance.TextDataAssets.MultiplayRoomOwnerTitle : Table.Instance.TextDataAssets.MultiplayRoomGuestTitle);
|
|
UpdatePingStatus(_isNetOk);
|
|
UpdateOfflineActions(_isNetOk);
|
|
}
|
|
|
|
public void UpdateNetStatus(bool isRoomOwner, bool isNetOk)
|
|
{
|
|
_isNetOk = isNetOk;
|
|
_isRoomOwner = isRoomOwner;
|
|
_isAISlot = false;
|
|
MultilingualManager.Instance.SetUIText(Prop, isRoomOwner ? Table.Instance.TextDataAssets.MultiplayRoomOwnerTitle : Table.Instance.TextDataAssets.MultiplayRoomGuestTitle);
|
|
UpdatePingStatus(isNetOk);
|
|
UpdateOfflineActions(isNetOk);
|
|
}
|
|
|
|
private void UpdateOfflineActions(bool isNetOk)
|
|
{
|
|
if (_isAISlot || _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;
|
|
|
|
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 || !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)
|
|
{
|
|
if (!isNetOk)
|
|
{
|
|
var offlineConfirm = Main.Instance?.ConfirmMap?.GetPlayerConfirm(_memberid);
|
|
Status.text = GetOfflineStatusText(offlineConfirm);
|
|
SetNetworkSprite(0);
|
|
return;
|
|
}
|
|
|
|
var confirm = Main.Instance?.ConfirmMap?.GetPlayerConfirm(_memberid);
|
|
if (confirm == null)
|
|
{
|
|
Status.text = "-- ms";
|
|
SetNetworkSprite(0);
|
|
return;
|
|
}
|
|
|
|
var pingMs = Mathf.RoundToInt(confirm.GetPing() * 1000f);
|
|
Status.text = $"{pingMs} ms";
|
|
SetNetworkSprite(GetNetworkLevel(pingMs));
|
|
}
|
|
|
|
private void UpdateAIStatus()
|
|
{
|
|
Status.text = "AI";
|
|
SetNetworkSprite(0);
|
|
SetNoInvite();
|
|
SetNoAIControls();
|
|
}
|
|
|
|
private string GetOfflineStatusText(PlayerConfirmData confirm)
|
|
{
|
|
if (confirm != null && confirm.AIControl) return "AI Control";
|
|
return confirm?.State switch
|
|
{
|
|
MemberNetState.Leaved => "Leaved",
|
|
MemberNetState.Disconnected => "Disconnected",
|
|
MemberNetState.Error => "Error",
|
|
_ => "Timeout"
|
|
};
|
|
}
|
|
|
|
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 string GetFallbackHumanName(ulong memberId)
|
|
{
|
|
return memberId == 0 ? "Empty" : $"Player {memberId}";
|
|
}
|
|
|
|
private string GetAIPlayerName(MemberCiv slot)
|
|
{
|
|
var seatNo = (slot?.Index ?? 0) + 1;
|
|
return $"AI {seatNo}P";
|
|
}
|
|
|
|
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
|
|
};
|
|
}
|
|
}
|
|
}
|