using UnityEngine; using System; using System.Collections; using System.Collections.Generic; using Sfs2X; using Sfs2X.Entities.Data; public class MessageManager { public BAServer server; public delegate void MessageCallBackDelegate(ISFSObject data); public delegate void MessageDealDelegate(string cmd, ISFSObject data); private Dictionary messageDealDict; private List receiveQueue; private BattleSession battleSession; private float craftSyncDistance = 10f; public MessageManager() { server = new BAServer(); server.SetMsgManCallBack(EnRecieveQueue); receiveQueue = new List (); //remove old message queue if exist MessageQueueUpdate mqu = GameObject.FindObjectOfType(); if(mqu != null) GameObject.Destroy(mqu.gameObject); //create new message queue GameObject mquObj = new GameObject("MessageQueueUpdate"); mqu = mquObj.AddComponent(); mqu.messageManager = this; messageDealDict = new Dictionary(); messageDealDict.Add(Command.ConnectionError, OnConnectionError); messageDealDict.Add(Command.SearchRoom, OnSearchBattle); messageDealDict.Add(Command.BattleInfo, OnBattleInfo); messageDealDict.Add (Command.BattleExit, OnExitBattle); messageDealDict.Add (Command.AITaker, OnAITaker); messageDealDict.Add (Command.PlayerJoin, OnPlayerJoin); messageDealDict.Add(Command.PlayerLeft, OnPlayerLeft); messageDealDict.Add(Command.Ready, OnReady); messageDealDict.Add (Command.State, OnState); messageDealDict.Add(Command.CraftSelection, OnSelectCraft); messageDealDict.Add(Command.Move, OnMove); messageDealDict.Add(Command.Attack, OnPower); messageDealDict.Add(Command.Dead, OnDead); messageDealDict.Add (Command.PrepareSwap, OnPrepareSwap); messageDealDict.Add (Command.RequestSwap, OnRequestSwap); messageDealDict.Add(Command.Radio, OnRadio); messageDealDict.Add(Command.Station, OnOccupyStation); messageDealDict.Add(Command.AddMapItem, OnAddMapItem); messageDealDict.Add(Command.GetMapItem, OnGetItem); messageDealDict.Add(Command.AddFlag, OnAddFlag); messageDealDict.Add(Command.GetFlag, OnGetFlag); messageDealDict.Add(Command.PutFlag, OnPutFlag); messageDealDict.Add(Command.CaptureFlag, OnCaptureFlag); messageDealDict.Add(Command.SimpleSync, OnSimpleSync); //clan state messageDealDict.Add (Command.ClanInit, OnClanInit); messageDealDict.Add (Command.ClanOnline, OnClanOnline); messageDealDict.Add (Command.ClanOffline, OnClanOffline); messageDealDict.Add (Command.ClanBattle, OnClanBattle); messageDealDict.Add (Command.ClanMessage, OnClanMessage); messageDealDict.Add (Command.ClanJoin, OnClanJoin); messageDealDict.Add (Command.ClanLeft, OnClanLeft); //team messageDealDict.Add (Command.TeamInvite, OnTeamInvite); messageDealDict.Add (Command.TeamJoin, OnTeamJoin); messageDealDict.Add (Command.TeamLeft, OnTeamLeft); messageDealDict.Add (Command.TeamState, OnTeamState); messageDealDict.Add (Command.TeamKick, OnTeamKick); } public void SetBattleSession(BattleSession battleSession) { this.battleSession = battleSession; } public int myUserId { get{ return Session.myUserId; } } private void EnSendQueue(Message msg) { server.Send(msg); } private void EnRecieveQueue(ISFSObject msg) { receiveQueue.Add (msg); } public void DeQueue() { if (BattleController.battleType == BattleController.BattleType.Edit) return; if (battleSession.IsReady ()) { for (int i = 0; i < receiveQueue.Count; i++) { ParseMessage (receiveQueue [i]); } receiveQueue.Clear (); } // else if(receiveQueue.Count > 0) { // ISFSObject msg = receiveQueue [0]; // receiveQueue.RemoveAt (0); // ParseMessage (msg); // } server.Update(); } private void ParseMessage(ISFSObject msg) { string cmd = msg.GetUtfString(Message.LABEL_COMMAND); ISFSObject data = msg.GetSFSObject(Message.LABEL_DATA); if(messageDealDict.ContainsKey(cmd)) { messageDealDict[cmd](cmd, data); } else { Debuger.LogError("Can not parse command["+cmd+"]"); } } private bool CheckError(string cmd, ISFSObject data) { if(data.ContainsKey("error")) { int error = data.GetInt ("error"); Debuger.LogError (data.GetUtfString("errormsg")); return true; } return false; } public void Connect() { server.Connect (); } private void OnConnectionError(string cmd, ISFSObject data) { ProgressPanel.Hide(); if(data.ContainsKey("success")) { if(!data.GetBool("success") && data.ContainsKey("error")) { int errorCode = data.GetInt("error"); string errorInfo = Language.GetStr("Connection", "connectFail")+"["+errorCode+"]"; // if(errorCode == SFSConnection.ERROR_CODE.LoginFailed.GetHashCode()) // { // errorInfo = Language.GetStr("Connection", "loginFail"); // } // else if(errorCode == SFSConnection.ERROR_CODE.ConnectLost.GetHashCode()) // { // errorInfo = Language.GetStr("Connection", "connectLost"); // } AlertPanel.Show(null, errorInfo, AlertPanel.OK, ConnectFail); } } } private void ConnectFail(AlertCloseEvent evt) { BattleController.battleType = BattleController.BattleType.Menu; Application.LoadLevel(Config.Scene.Base.ToString()); } public void Disconnect() { server.Disconnect(); } public void EnterBase() { server.EnterBase (); } public void SearchBattle(MapData.Mode mode) { LocalToRemote (); battleSession.mode = mode; LoadingPanel panel = LoadingPanel.Show (); LoadingPanel.Increase (0.1f); panel.ReachTargetProgress.AddListener (()=>{ server.SearchRoom (); }); } private void OnSearchBattle(string cmd, ISFSObject data) { if(!CheckError(cmd, data)) { string mapId = data.GetUtfString("m"); battleSession.mapId = MapData.GetMapIdByName(mapId); if (battleSession.mapId != MapData.MapID.Base) { BattleController.battleType = BattleController.BattleType.Battle; battleSession.ResetBattle (); } else { BattleController.battleType = BattleController.BattleType.Menu; } int aiTakerUserId = StringUtil.ToInt(data.GetUtfString ("c")); battleSession.aiTakerUserId = aiTakerUserId; //init player ParsePlayer(data.GetSFSArray("a")); if (battleSession.mapId != MapData.MapID.Base) LoadingPanel.LoadScene (mapId); else { if (Session.GetInstance ().myUserData.isLogin) { CheckConnection (); } else { LoadingPanel.Increase (0.2f); Session.GetInstance ().GetNetworkManager ().Login (() => { EquipManager.GetInstance().RequestInventory(); battleSession.GetBattleController ().menuUI.clanChatBar.Refresh (); battleSession.SetMyPlayerId(Session.myUserId); CheckConnection (); if (LocalSaver.GetInstance ().noAutoBinding == 0) Session.GetInstance ().GetNetworkManager ().Binding (); }); } } } } private void ParsePlayer(ISFSArray arr) { for(int i=0; i(); ai.init(battleSession.GetBattleController()); Player player = battleSession.GetPlayer(craftData.userId); ai.SetPlayer(player); battleSession.GetBattleController().battleUI.miniMap.CreateCraft(door); map.AddBattleObject(door); } else if(typeId == MapObjectUtil.TypeId.MapItemPos) { int id = obj.GetInt("i"); int itemId = obj.GetInt("t"); if(itemId != -1) { MapItemData itemData = new MapItemData(); itemData.id = id; itemData.typeId = itemId; MapItemPos mapItemPos = battleSession.GetBattleController().GetMap().GetMapItemPos(id); itemData.postion = mapItemPos.position; MapItem mapItem = battleSession.GetBattleController().GetMap().CreateMapItem(itemData); mapItemPos.item = mapItem; } } else if(typeId == MapObjectUtil.TypeId.Flag) { int id = obj.GetInt("i"); int itemId = obj.GetInt("t"); if(itemId != -1) { MapItemData itemData = new MapItemData(); itemData.id = id; itemData.typeId = itemId; MapItemPos mapItemPos = battleSession.GetBattleController().GetMap().GetMapItemPos(id); itemData.postion = mapItemPos.position; MapItem mapItem = battleSession.GetBattleController().GetMap().CreateMapItem(itemData); mapItemPos.item = mapItem; } } } map.RemoveNoIdDoor(); } private void OnPlayerLeft(string cmd, ISFSObject data) { if(!battleSession.IsReady() || battleSession.IsOver()) return; int userId = StringUtil.ToInt(data.GetUtfString("u")); battleSession.PlayerLeft (userId); } private void RemoteToLocal() { server.SetConnection (BAServer.ConnectionType.Local); } private void LocalToRemote() { server.SetConnection (BAServer.ConnectionType.Remote); } public void Ready() { ISFSObject data = new SFSObject(); Message msg = new Message(Command.Ready, data); EnSendQueue(msg); } private void OnReady(string cmd, ISFSObject data) { if (data != null) { int receiver = data.GetInt ("r"); if(receiver != myUserId) { SendState (receiver); return; } int freeTime = data.GetInt ("f"); int time = data.GetInt ("t"); battleSession.GetBattleController ().clock.freeTimeLeft = (float)freeTime / 1000f; battleSession.GetBattleController ().clock.timeLeft = (float)time / 1000f; ParseBuilding (data.GetSFSArray ("l")); if (data.ContainsKey ("a")) ParsePlayer (data.GetSFSArray ("a")); } WaitLoadComplete (); } private void CheckConnection() { if (Session.GetInstance ().myUserData.clanId > 0) { LocalToRemote (); battleSession.GetMessageManager ().Ready (); } else { // battleSession.GetMessageManager ().Connect (); RemoteToLocal (); OnReady (Command.Ready.ToString(), null); } } private void WaitLoadComplete() { if(LoadingPanel.GetCurrentPanel() != null) LoadingPanel.Complete (OnLoadBattleComplete); } private void OnLoadBattleComplete() { battleSession.GetBattleController().ReadyToFight(); } private void SendState(int target) { ISFSArray arr = new SFSArray (); PlayerCraftObjToArr (battleSession.myPlayer, arr); if (battleSession.aiTakerUserId == myUserId) { List list = battleSession.GetPlayerList (); for(int i=0; i craftSyncDistance) // craft.position = startPos; craft.MoveTo(x, y); } else { Debuger.LogError("onReceiveMove::can not find craft with id("+craftId+")"); } } public void Target(Craft craft) { ISFSObject data = new SFSObject(); data.PutInt("i", craft.id); PackTarget(craft.target, data); Message msg = new Message(Command.Target, data); EnSendQueue(msg); } private void PackTarget(ITarget target, ISFSObject data) { if(target is BattleObject) { BattleObject battleObj = target as BattleObject; data.PutInt("ti", battleObj.id); data.PutInt("tt", TargetUtil.GetTargetType(battleObj).GetHashCode()); } } private void OnTarget(string cmd, ISFSObject data) { Craft craft = battleSession.GetBattleController().GetMap().GetBattleObject(data.GetInt("i")) as Craft; if(craft != null && craft.userId != myUserId) { craft.target = ParseTarget(data); if(craft.target == null) { craft.StopMove(); } } } private ITarget ParseTarget(ISFSObject data) { if(data.ContainsKey("ti")) { int targetId = data.GetInt("ti"); TargetUtil.TargetType targetType = TargetUtil.GetTargetTypeByCode(data.GetInt("tt")); if(targetType == TargetUtil.TargetType.CrystalBase) { return battleSession.GetBattleController().GetMap().GetCrystalBase(targetId).GetStation(); } else if(targetType == TargetUtil.TargetType.Craft) { return battleSession.GetBattleController().GetMap().GetBattleObject(targetId); } } return null; } public void Power(Power power, ITarget target) { ISFSObject powerData = power.PackMessage(target, battleSession.GetBattleController()); Message msg = new PowerMessage(power, powerData); EnSendQueue(msg); } private void OnPower(string cmd, ISFSObject data) { int userId = data.GetInt ("u"); int craftId = data.GetInt("i"); int typeId = data.GetInt ("t"); int powerId = data.GetInt("p"); ISFSObject powerData = data.GetSFSObject("d"); IPowerOwner owner = null; if(typeId == MapObjectUtil.TypeId.UAV.GetHashCode()) owner = battleSession.GetBattleController().GetMap().GetUAVehicle(userId) as IPowerOwner; else owner = battleSession.GetBattleController().GetMap().GetBattleObject(craftId) as IPowerOwner; if(owner != null) { Vector3 pos = new Vector3(data.GetFloat("x"), 0, data.GetFloat("y")); if(NumberUtil.distanceVector3(owner.position, pos, true) > craftSyncDistance) owner.position = pos; owner.GetPowerManager ().ParsePower (powerId, powerData, battleSession.GetBattleController ()); } else { Debuger.LogError("onReceivePower::can not find craft with id("+craftId+")"); } } public void Dead(BattleObject battleObj, int killerUserId, int killerCraftId) { ISFSObject data = new SFSObject(); data.PutInt("i", battleObj.id); data.PutInt("m", battleObj.team.GetHashCode()); data.PutInt("c", battleObj is Craft ? (battleObj as Craft).GetCraftId() : 0); data.PutInt("t", battleObj.typeId); data.PutInt("u", battleObj.userId); data.PutInt("ku", killerUserId); data.PutInt("kc", killerCraftId); data.PutInt("x", battleObj.col); data.PutInt("y", battleObj.row); Message msg = new Message(Command.Dead, data); EnSendQueue(msg); if(battleObj.userId == myUserId) { battleSession.GetBattleController().DealDeath(battleObj.userId, battleObj.id, killerUserId); } } private void OnDead(string cmd, ISFSObject data) { int objid = data.GetInt("i"); TeamUtil.Team team = TeamUtil.GetTeam (data.GetInt("m")); int killerUserId = data.GetInt("ku"); Map map = battleSession.GetBattleController ().GetMap (); IBattleObject battleObj = map.GetBattleObject(objid); if (battleObj != null) { battleSession.GetBattleController().DealDeath(battleObj.userId, battleObj.id, killerUserId); } team = TeamUtil.GetOpponentTeam (team); FlagItem flag = map.GetFlag(team); if(flag != null && flag.linkedCraftId == objid) { int x = data.GetInt("x"); int y = data.GetInt("y"); Vector3 pos = new Vector3 (Map.GetCenterX(x), 0, Map.GetCenterZ(y)); flag.PutGround(pos); Player player = battleSession.GetPlayer(data.GetInt("u")); if(player != null) { string info = Language.GetStr("Flag", "flagLose"); info = info.Replace("%COLOR%", TeamUtil.GetTeamColorString(player.team)); info = info.Replace("%NICK%", player.nick); info = info.Replace("%TEAM%", TeamUtil.GetTeamName(team)); battleSession.GetBattleController().battleUI.ShowBottomTip(info); } } } public void OccupyStation(Craft craft, CrystalBase crystalBase) { ISFSObject data = new SFSObject(); data.PutInt("c", crystalBase.id); data.PutInt("t", craft.team.GetHashCode()); data.PutInt("u", craft.userId); Message msg = new Message(Command.Station, data); EnSendQueue(msg); } private void OnOccupyStation(string cmd, ISFSObject data) { if(data.ContainsKey("i")) { Map map = battleSession.GetBattleController().GetMap(); int userId = data.GetInt ("u"); StationData stationData = new StationData(); stationData.team = TeamUtil.GetTeam(data.GetInt("t")); stationData.userId = userId; stationData.id = data.GetInt("i"); stationData.crystalId = data.GetInt("c"); Station station = map.CreateStation(stationData, battleSession.GetBattleController()); Player player = battleSession.GetPlayer(userId); if(player != null) { player.station++; string colorStr = TeamUtil.GetTeamColorString(player.team); string info = Language.GetStr("GameInfo", "occupy"); if(player.userId == myUserId) { info = info.Replace("%NAME%", Language.GetStr("GameInfo", "you")); } else { info = info.Replace("%NAME%", player.nick); } info = info.Replace("%COLOR%", colorStr); battleSession.GetBattleController().battleUI.ShowBottomTip(info); } } } private bool radioHold = false; public void Radio(int index) { if(!radioHold) { ISFSObject data = new SFSObject(); data.PutInt("i", index); data.PutInt("u", myUserId); int craftId = battleSession.GetBattleController ().GetCtrlCraft() != null ? battleSession.GetBattleController ().GetCtrlCraft().id : 0; data.PutInt ("c", craftId); radioHold = true; Message msg = new Message(Command.Radio, data); EnSendQueue(msg); } battleSession.GetBattleController().battleUI.HideRadioPanel(); } private void OnRadio(string cmd, ISFSObject data) { int userId = data.GetInt("u"); int index = data.GetInt("i"); int craftId = data.GetInt ("c"); if(userId == myUserId) { radioHold = false; } battleSession.GetBattleController().battleUI.DealRadio(userId, craftId, index); } // private void ResetPlayer(Player player) // { // player.heroDeadTime = 0; // if(player.heroCraft != null) // { // battleSession.GetBattleController().DoDeath(player.heroCraft); // } // player.ClearHero(); // } // public static void ParseStaticMapObject(ISFSArray arr, BattleSession battleSession) // { // ParseBuilding(arr); // for(int i=0; i{ LoadingPanel.LoadScene(Config.Scene.Base.ToString()); }); } public void ClanInit() { ISFSObject data = new SFSObject (); Message msg = new Message (Command.ClanInit, data); EnSendQueue (msg); } private void OnClanInit(string cmd, ISFSObject data) { } private void OnClanOnline(string cmd, ISFSObject data) { if(data.ContainsKey("a")) InviteManager.GetInstance ().SetData (data.GetSFSArray ("a")); if (data.ContainsKey ("i")) { InviteManager.GetInstance ().Add (StringUtil.ToInt (data.GetUtfString ("i")), InviteData.State.Online); InviteManager.GetInstance ().Sort (); } } private void OnClanOffline(string cmd, ISFSObject data) { InviteManager.GetInstance ().Offline (StringUtil.ToInt (data.GetUtfString("i"))); } private void OnClanBattle(string cmd, ISFSObject data) { int id = StringUtil.ToInt (data.GetUtfString("i")); InviteManager.GetInstance ().Battle (id); } public void ClanMessage(string content) { ISFSObject data = new SFSObject (); data.PutInt ("u", myUserId); data.PutUtfString ("m", content); Message msg = new Message (Command.ClanMessage, data); EnSendQueue (msg); } private void OnClanMessage(string cmd, ISFSObject data) { if (!CheckError (cmd, data)) { int userId = data.GetInt ("u"); string content = data.GetUtfString ("m"); ChatManager.GetInstance ().AddClanMsg (userId, content); } } public void ClanJoin() { if (Session.GetInstance ().myUserData.clanId > 0) { LocalToRemote (); ISFSObject data = new SFSObject (); data.PutInt (UserSFSObjectLabel.CLAN, Session.GetInstance().myUserData.clanId); Message msg = new Message (Command.ClanJoin, data); EnSendQueue (msg); } } private void OnClanJoin(string cmd, ISFSObject data) { Ready (); } public void ClanLeft() { Message msg = new Message (Command.ClanLeft, new SFSObject ()); EnSendQueue (msg); } private void OnClanLeft(string cmd, ISFSObject data) { List list = battleSession.GetPlayerList (); for(int i=0; i{ if(evt.detail == AlertPanel.YES) { TeamJoin(id); } }); } public void TeamJoin(int id) { ISFSObject data = new SFSObject (); data.PutUtfString ("t", id.ToString()); Message msg = new Message (Command.TeamJoin, data); EnSendQueue (msg); } private void OnTeamJoin(string cmd, ISFSObject data) { } public void TeamLeft() { ISFSObject data = new SFSObject (); Message msg = new Message (Command.TeamLeft, data); EnSendQueue (msg); } private void OnTeamLeft(string cmd, ISFSObject data) { } public void TeamKick(int id) { ISFSObject data = new SFSObject (); data.PutUtfString ("t", id.ToString()); Message msg = new Message (Command.TeamKick, data); EnSendQueue (msg); } private void OnTeamKick(string cmd, ISFSObject data) { } private void OnTeamState(string cmd, ISFSObject data) { int leader = StringUtil.ToInt (data.GetUtfString (UserSFSObjectLabel.TEAM_LEADER_ID)); if (data.ContainsKey (UserSFSObjectLabel.TEAM)) { InviteManager.GetInstance().TeamState(leader, data.GetSFSArray(UserSFSObjectLabel.TEAM)); } else{ InviteManager.GetInstance().TeamState(leader, null); } } public void Dispose() { Disconnect(); } }