using System; using UnityEngine; using System.Collections.Generic; using System.Linq; using LitJson; using Sfs2X.Core; using Sfs2X.Entities; using Sfs2X.Entities.Data; using Sfs2X.Requests; using Sfs2X.Entities.Variables; using UnityEngine.UI; public class SFSPlazaRoomManager { public class PlazaRoomPlayer { #region Config public string NickName; public Player Player; public Transform NickNameTransform; public Transform MessageBox; public List TweenRoots; #endregion public PlazaRoomPlayer(Player player, string nickname) { Player = player; TweenRoots = new List(); NickNameTransform = ManaReso.Get("NickName", Folder.UI, false, ManaReso.Get("W_HudParent"), false, ObjType.NickName); HudTarget hudTarget = NickNameTransform.GetComponent(); if (hudTarget == null) { hudTarget = NickNameTransform.AddComponent(); } hudTarget.PosTra = Player.ChildDic["NickName"]; hudTarget.SetPosition(); NickName = string.IsNullOrEmpty(nickname) ? Language.GetStr("UI", "未命名") : nickname; NickNameTransform.GetComponent().text = NickName; MessageBox = ManaReso.Get("MessageBox", Folder.UI, false, ManaReso.Get("W_HudParent"), false, ObjType.MessageBox); MessageBox.GetComponentInChildren().VerticalMinSize = 12; MessageBox.GetComponentInChildren().VerticalMaxSize = 20; hudTarget = MessageBox.GetComponent(); if (hudTarget == null) { hudTarget = MessageBox.AddComponent(); } hudTarget.PosTra = Player.ChildDic["MessageBox"]; MessageBox.CreateTweenCG(0, 1, 0.25f, true, true, Curve.EaseOutQuad).InOrigin = true; } public void Save() { foreach (var tweenRoot in TweenRoots) { tweenRoot.Pause(); } ManaReso.Save(Player); ManaReso.Save(NickNameTransform); ManaReso.Save(MessageBox); Player.PlayAnim(Player.IdleAnimationName); } public bool IsMoving; public float Speed = 1f; public Vector3 Destination; public TweenVec MoveTween; public void MoveTo(Vector3 destination) { if (destination.Equal(Player.transform.position)) { return; } if (destination.x > Player.transform.position.x) { Player.Flip(PlayerDirection.Right); } else { Player.Flip(PlayerDirection.Left); } float duration = Mathf.Clamp(Vector3.Magnitude(destination - Player.transform.position) / 1.5f, 0.25f, 10f) / Speed; MoveTween = Player.transform.CreateTweenVec3D(destination, duration, false, true, true, Curve.EaseOutQuad); MoveTween.StartForward(); MoveTween.AddEventOnetime(EventType.ForwardFinish, StopMove); TweenRoots.Add(MoveTween); IsMoving = true; Destination = destination; Player.PlayAnim(Player.WalkAnimationName); } public void StopMove() { IsMoving = false; Player.PlayAnim(Player.IdleAnimationName); } public float MessgeTime = 3f; public Coroutine MessgeCoroutine; public void ShowMessage(string message) { if (MessgeCoroutine != null) { Auxiliary.Instance.StopCoroutine(MessgeCoroutine); } MessageBox.GetChild(0).GetComponent().text = message; MessageBox.TweenForCG(); MessgeCoroutine = Auxiliary.Instance.DelayCall(() => { MessageBox.TweenBacCG(); }, MessgeTime); } } #region Variable public GardenSmartFox GardenSmartFox; public User SelfUser; public PlazaRoomPlayer SelfInstance; public Room CurrentPlazaRoom; public bool InPlazaRoom { get { return CurrentPlazaRoom != null; } } public bool EnteringPlazaRoom; public bool IsBlackMaskFinish; public RequestStatus JoinRoomStatus = RequestStatus.Pending; public Dictionary UserInstanceDictionary = new Dictionary(); #endregion public void OnEnterPlazaRoomButton() { IsBlackMaskFinish = false; EnteringPlazaRoom = true; ManaReso.Get("B_SignIn0").TweenBacCG(); ManaReso.Get("T_NickName").TweenBacCG(); ManaCenter.SceneSwitchLock = true; TweenRoot tweenRoot = ManaReso.Get("V_BlackMask").TweenBacCG(); tweenRoot.AddEventOnetime ( EventType.BackwardFinish, () => { IsBlackMaskFinish = true; TryEnterPlazaRoom(); } ); GardenSmartFox.ExecuteAfterCheckConection ( () => { GardenSmartFox.SFSPlazaRoomManager.JoinRoomStatus = RequestStatus.Pending; GardenSmartFox.ExtensionManager.PlazaRoomExtension.JoinPlazaRoom(); }, (succeed, baseEvent) => { if (!succeed) { GardenSmartFox.SFSPlazaRoomManager.JoinRoomStatus = RequestStatus.Failed; TryEnterPlazaRoom(); } }, (succeed, baseEvent) => { if (!succeed) { GardenSmartFox.SFSPlazaRoomManager.JoinRoomStatus = RequestStatus.Failed; TryEnterPlazaRoom(); } } ); } public void TryEnterPlazaRoom() { if (!GardenSmartFox.SFSPlazaRoomManager.IsBlackMaskFinish) { return; } if (!GardenSmartFox.SFSPlazaRoomManager.EnteringPlazaRoom) { return; } if (GardenSmartFox.SFSPlazaRoomManager.JoinRoomStatus == RequestStatus.Pending) { return; } if (GardenSmartFox.SFSPlazaRoomManager.JoinRoomStatus == RequestStatus.Failed) { QuitPlazaRoom(); Bubble.Show(null, Language.GetStr("UI", "加入房间失败"), null, null, () => { ManaReso.Get("V_BlackMask").TweenForCG();},null,false); EnteringPlazaRoom = false; } else if (GardenSmartFox.SFSPlazaRoomManager.JoinRoomStatus == RequestStatus.Succeed) { EnterPlazaRoom(); EnteringPlazaRoom = false; } } private Vector3 PlayerDefaultPosition; public void EnterPlazaRoom() { PlazaRoom.Initialize(); foreach (var kv in UserInstanceDictionary) { if (kv.Value.Player.transform.parent == null) kv.Value.Player.transform.parent = ManaReso.Get("PlazaRoom"); } ManaGarden.RetrieveAllElf(); GardenSmartFox.SFSPlazaRoomManager.PlazaRoomSky = ManaReso.Get("PlazaRoomSky"); SkyOriginPosition = GardenSmartFox.SFSPlazaRoomManager.PlazaRoomSky.position; GardenSmartFox.SFSPlazaRoomManager.PlazaRoomCamera = ManaReso.Get("MainCamera"); GardenSmartFox.SFSPlazaRoomManager.CameraOriginPosition = GardenSmartFox.SFSPlazaRoomManager.PlazaRoomCamera.transform.position; //Debug.Log(GardenSmartFox.User.Id); SelfUser = GardenSmartFox.User; PlayerDefaultPosition = ManaReso.Get("PlazaRoomDefaultPosition").position; SelfInstance = InstantiatePlayer(SelfUser, ManaNickName.NickName, PlayerDefaultPosition, PlayerDirection.Left, ManaData.GetDressDataIDs(ManaPlayer.Player)); SelfInstance.Player.transform.position += new Vector3(0, 0, -0.001f); UserInstanceDictionary.Add(SelfUser, SelfInstance); SendInstantiateRequset(-1); GardenSmartFox.SFSPlazaRoomManager.CameraLeftBorder = ManaReso.Get("PlazaRoomCameraLeftBorder").position.x; GardenSmartFox.SFSPlazaRoomManager.CameraRightBorder = ManaReso.Get("PlazaRoomCameraRightBorder").position.x; GardenSmartFox.SFSPlazaRoomManager.PlazaRoomCamera.transform.SetX(GardenSmartFox.SFSPlazaRoomManager.CameraLeftBorder); ManaReso.Get("V_BlackMask").TweenForCG(); ManaReso.SetActive("C_Main2", false); ManaReso.SetActive("Garden", false); ManaReso.SetActive("PlazaRoom", true); ManaReso.SetActive("W_HudParent", true); ManaReso.SetActive("X_PlazaRoom", true); } public void ExitPlazaRoom() { QuitPlazaRoom(); TweenRoot tweenRoot = ManaReso.Get("V_BlackMask").TweenBacCG(); tweenRoot.AddEventOnetime ( EventType.BackwardFinish, () => { PlazaRoomSky.position = SkyOriginPosition; PlazaRoomCamera.transform.position = CameraOriginPosition; ManaReso.SetActive("C_Main2", true); ManaReso.SetActive("Garden", true); ManaReso.SetActive("PlazaRoom", false); ManaReso.SetActive("W_HudParent", false); ManaReso.SetActive("X_PlazaRoom", false); ManaReso.Get("V_BlackMask").TweenForCG(); ManaReso.Get("B_SignIn0").TweenForCG(); ManaReso.Get("T_NickName").TweenForCG(); foreach (var kv in UserInstanceDictionary) { kv.Value.Save(); } UserInstanceDictionary = new Dictionary(); } ); } public void QuitPlazaRoom() { ManaCenter.SceneSwitchLock = false; GardenSmartFox.SmartFox.Send(new LeaveRoomRequest(CurrentPlazaRoom)); GardenSmartFox.SFSPlazaRoomManager.CurrentPlazaRoom = null; } public SFSPlazaRoomManager(GardenSmartFox gardenSmartFox) { GardenSmartFox = gardenSmartFox; GardenSmartFox.ExtensionManager.PlazaRoomExtension.onExitPlazaRoom += OnExitPlazaRoom; GardenSmartFox.ExtensionManager.PlazaRoomExtension.onJoinPlazaRoom += OnJoinPlazaRoom; GardenSmartFox.ExtensionManager.PlazaRoomExtension.onUserExitCurrentPlazaRoom += OnUserExitPlazaRoom; GardenSmartFox.ExtensionManager.PlazaRoomExtension.onUserEnterCurrentPlazaRoom += OnUserEnterPlazaRoom; GardenSmartFox.ExtensionManager.PlazaRoomExtension.onSynchronize += Synchronize; GardenSmartFox.ExtensionManager.PlazaRoomExtension.onReceiveExpression += ReceiveExpression; GardenSmartFox.ExtensionManager.PlazaRoomExtension.onReceivePublicMessage += ReceivePublicMessage; GardenSmartFox.ExtensionManager.PlazaRoomExtension.onInstantiate += OnInstantiate; gardenSmartFox.Connector.onConnectionLost += OnConectionLost; } public void Update() { if (!InPlazaRoom) return; if (EnteringPlazaRoom) return; //KeepAliveThread(); CameraControllThread(); } public float KeepAliveTime = 30; public float KeepAliveTimer; public void KeepAliveThread() { KeepAliveTimer += Time.deltaTime; if (KeepAliveTimer > KeepAliveTime) { KeepAliveTimer = 0; GardenSmartFox.AddRequest(GardenSmartFox.ConstructCommandParameter(CommandID.KeepAlive.GetHashCode(), new SFSObject(), 0), RequestType.Immediate); } } public float CameraLeftBorder; public float CameraRightBorder; public Vector3 CameraOriginPosition; public Camera PlazaRoomCamera; public void CameraControllThread() { if (PlazaRoomCamera == null) { return; } float x; if (SelfInstance.Player.transform.position.x <= CameraLeftBorder) { x = Mathf.Lerp(PlazaRoomCamera.transform.position.x, CameraLeftBorder, Time.deltaTime); if (SkyTween != null) SkyTween.Pause(); } else if (SelfInstance.Player.transform.position.x >= CameraRightBorder) { x = Mathf.Lerp(PlazaRoomCamera.transform.position.x, CameraRightBorder, Time.deltaTime); if (SkyTween != null) SkyTween.Pause(); } else { x = Mathf.Lerp(PlazaRoomCamera.transform.position.x, SelfInstance.Player.transform.position.x, Time.deltaTime); } PlazaRoomCamera.transform.SetX(x); } public void MoveTo(Vector3 destination) { GardenSmartFoxManager.GardenSmartFox.SFSPlazaRoomManager.SelfInstance.MoveTo(destination); GardenSmartFoxManager.GardenSmartFox.SFSPlazaRoomManager.SendSynchronizeDestination(destination); MoveSky(SelfInstance.MoveTween.Duration, SelfInstance.MoveTween.Delta); } private float SkyMoveRatio = 0.1f; private Vector3 SkyOriginPosition; private TweenRoot SkyTween; public Transform PlazaRoomSky; private void MoveSky(float duration, Vector3 offset) { offset *= -SkyMoveRatio; offset.y = 0; offset.z = 0; SkyTween = PlazaRoomSky.transform.CreateTweenVecOffset2D(offset, duration, false, true, true, Curve.Linear); SkyTween.StartForward(); } public void OnConectionLost(BaseEvent baseEvent) { if (InPlazaRoom) { OnExitPlazaRoom(); } } public void OnExitPlazaRoom() { ExitPlazaRoom(); } public void OnJoinPlazaRoom(Room room) { GardenSmartFox.SFSPlazaRoomManager.CurrentPlazaRoom = room; JoinRoomStatus = RequestStatus.Succeed; TryEnterPlazaRoom(); } public void OnUserExitPlazaRoom(User user) { UserInstanceDictionary[user].Save(); UserInstanceDictionary.Remove(user); } public void OnUserEnterPlazaRoom(User user) { SendInstantiateRequset(user); } public void Synchronize(User sender, SFSObject parameter) { if (!UserInstanceDictionary.ContainsKey(sender)) return; if (sender.IsItMe) return; if (parameter.ContainsKey(DataID.Destination.GetHashString())) { Vector3 destination = parameter.GetUtfString(DataID.Destination.GetHashString()).StringToVector(); SynchronizeDestination(destination, sender); } if (parameter.ContainsKey(DataID.Close.GetHashString())) { List closeIDs = parameter.GetIntArray(DataID.Destination.GetHashString()).ToList(); SynchronizeClose(closeIDs, sender); } //Debug.LogWarning(sender.IsItMe + " : " + jsonData.ToJson()); } public void SynchronizeClose(List closeIDs, User sender) { Player player = UserInstanceDictionary[sender].Player; foreach (var closeID in closeIDs) { CloseUnit closeUnit = ManaPlayer.CloseUnitDic[closeID]; player.ChangeClose(closeUnit.BodyPart, closeUnit.ArmatureName); } } public void SynchronizeDestination(Vector3 destination, User sender) { UserInstanceDictionary[sender].MoveTo(destination); } private float ExpressionDuration = 1; public void ReceiveExpression(int expressionID, User sender) { PlazaRoomPlayer plazaRoomPlayer = UserInstanceDictionary[sender]; string expressionName = Enum.GetName(typeof(ExpressionID), expressionID); plazaRoomPlayer.Player.ChangeExpression(expressionName, ExpressionDuration); string message = $"{plazaRoomPlayer.NickName}:\u3000<({expressionName}按钮)>"; ManaInfoBox.Show(InfoCategory.PlazaRoom, message, Mathf.Infinity, ManaReso.LoadSprite("Expression", Folder.Scene)); ManaReso.SetText("X_CurrentInfoLab", message); } public void ReceivePublicMessage(string message, User sender) { //Debug.Log(sender.Id); PlazaRoomPlayer plazaRoomPlayer = UserInstanceDictionary[sender]; plazaRoomPlayer.ShowMessage(message); message = $"{plazaRoomPlayer.NickName}:\u3000{message}"; ManaInfoBox.Show(InfoCategory.PlazaRoom, message, Mathf.Infinity, ManaReso.LoadSprite("Expression", Folder.Scene)); ManaReso.SetText("X_CurrentInfoLab", message); } public void OnInstantiate(User user, SFSObject parameter) { if (user.IsItMe) return; UserInstanceDictionary.Add(user, InstantiatePlayer(user, parameter)); } public void SendExpression(ExpressionID expressionID) { GardenSmartFoxManager.GardenSmartFox.ExtensionManager.PlazaRoomExtension.SendExpression(expressionID); } //private string LastPublicMessage; public bool SendPublicMessage(string message) { if (string.IsNullOrEmpty(message)) { Bubble.Show(null, Language.GetStr("UI", "内容不能为空")); return false; } //else if (LastPublicMessage == message) //{ // Bubble.Show(null, Language.GetStr("UI", "请勿重复发送")); // return false; //} else { //LastPublicMessage = message; message = StringFilter.GetFilteredString(message); GardenSmartFoxManager.GardenSmartFox.ExtensionManager.PlazaRoomExtension.SendPublicMessage(message); //ManaInfoBox.Show(InfoCategory.PlazaRoom, $"{SelfUser.Name} : {message}", 10, ManaReso.LoadSprite("Expression", Folder.Scene)); return true; } } public void SendInstantiateRequset(User receiver) { SendInstantiateRequset(receiver.Id); } public void SendInstantiateRequset(int receiverID) { SFSObject parameter = new SFSObject(); parameter.PutInt(DataID.SenderID.GetHashString(), GardenSmartFox.User.Id); parameter.PutIntArray(DataID.Close.GetHashString(), ManaData.GetDressDataIDs(SelfInstance.Player).ToArray()); parameter.PutUtfString(DataID.Position.GetHashString(), SelfInstance.Player.transform.position.VectorToString()); parameter.PutInt(DataID.PlayerDirection.GetHashString(), SelfInstance.Player.PlayerDirection.GetHashCode()); parameter.PutUtfString(DataID.NickName.GetHashString(), ManaNickName.NickName); GardenSmartFox.AddRequest(GardenSmartFox.ConstructCommandParameter(CommandID.Instantiate.GetHashCode(), parameter, receiverID), RequestType.Immediate); if (SelfInstance.IsMoving) { SendSynchronizeDestination(SelfInstance.Destination); } } public void SendSynchronizeDestination(Vector3 destination) { GardenSmartFoxManager.GardenSmartFox.ExtensionManager.PlazaRoomExtension.SendSynchronizeDestination(destination); } public PlazaRoomPlayer InstantiatePlayer(User user, string nickName, Vector3 position, PlayerDirection direction, List dressDataIDs) { Transform parent = ManaReso.Get("PlazaRoom", false); Transform tra = ManaReso.Get("Player", Folder.Scene, false, parent, false, ObjType.Player); Player player = tra.GetComponent(); if (player == null) { player = tra.AddScript(); player.Build(); } foreach (var id in dressDataIDs) { CloseUnit closeUnit = ManaPlayer.CloseUnitDic[id]; closeUnit.ChangeDress(player); } player.SetAllCollider(false); player.transform.position = position; player.Flip(direction); tra.localScale = new Vector3(0.525f, 0.525f, 0.525f); return new PlazaRoomPlayer(player, nickName); } public PlazaRoomPlayer InstantiatePlayer(User user, SFSObject parameter) { List dressDatas = ManaData.GetDressDataIDs(parameter); Vector3 position = parameter.GetUtfString(DataID.Position.GetHashString()).StringToVector(); PlayerDirection direction = (PlayerDirection) parameter.GetInt(DataID.PlayerDirection.GetHashString()); string nickName = parameter.GetUtfString(DataID.NickName.GetHashString()); PlazaRoomPlayer plazaRoomPlayer = InstantiatePlayer(user, nickName, position, direction, dressDatas); return plazaRoomPlayer; } }