/// <summary> /// 移除掉某个对象身上的事件处理 /// 一般在他的OnDestory里执行 /// </summary> /// <param name="self">this 扩展,扩展对象必须是IMsgReceiver 的实例</param> /// <param name="MsgType">消息类型</param> public static void RemoveMessageHandler(this IMsgReceiver self, ECustomMessageType MsgType) { if (MsgType == ECustomMessageType.NULL) { CLOG.E("error msg type is {0}", MsgType); return; } // 没有注册该消息时的处理 if (!m_MsgHandlerList.ContainsKey(MsgType)) { return; } // 得到所有注册的处理 var Handlers = m_MsgHandlerList[MsgType]; // 得到数量 var HandlerCount = Handlers.Count; // 倒序遍历,防止删除引起的循环异常 for (int i = HandlerCount - 1; i >= 0; i--) { var Handler = Handlers[i]; // 存在处理对象才调用 if (Handler.m_Receiver == self) { Handlers.Remove(Handler); } } }
/// <summary> /// 在当前Socekt上发送CMessage消息 /// </summary> /// <param name="message">消息,可由任意继承了PackageBase的对象调用 ToMessage获得</param> /// <returns>发送的字节数</returns> public int SendMessage(CMessage message) { try { int nowSend = 0; byte[] data = message.GetData(); while (nowSend < data.Length) { int sendSize = m_Socket.Send(data, nowSend, 1024, SocketFlags.None); nowSend += sendSize; } return(nowSend); } catch (ArgumentNullException e) { CLOG.E(e.ToString()); return(-1); } catch (SocketException e) { CLOG.E(e.ToString()); return(-2); } catch (ObjectDisposedException e) { CLOG.E(e.ToString()); return(-3); } }
/// <summary> /// 注册消息处理 /// </summary> /// <param name="self">this扩展,this必须是 ImsgReceiver 的实例</param> /// <param name="MsgType"> 消息名 </param> /// <param name="Callback"> 回调函数,无返回值,支持任意类型,任意长度的参数 </param> public static void AddMessageHandler(this IMsgReceiver self, ECustomMessageType MsgType, DelegateCustomMessage Callback) { if (MsgType == ECustomMessageType.NULL) { CLOG.E("error msg type is {0}", MsgType); return; } if (Callback == null) { CLOG.E("none call back!!", MsgType); return; } if (!m_MsgHandlerList.ContainsKey(MsgType)) { // 如果不包含这个Key,那么就创建他 m_MsgHandlerList[MsgType] = new List <LogicMsgHandler>(); } // 防止反复注册 foreach (var item in m_MsgHandlerList[MsgType]) { if (item.m_Receiver == self && item.m_Callback == Callback) { return; } } // 注册 m_MsgHandlerList[MsgType].Add(new LogicMsgHandler(self, Callback)); }
/// <summary> /// 预加载所有需要用到的预制体 /// </summary> /// <returns>加载成功与否</returns> public bool CacheAllPrefab() { try { //读取所有预制体 UnityEngine.Object[] AllPrefabs = Resources.LoadAll(PREFAB_PATH); for (int i = 0; i < AllPrefabs.Length; i++) { #if UNITY_EDITOR if (m_PrefabCache.ContainsKey(AllPrefabs[i].name)) { CLOG.E("the key {0} has already add to prefab cache", AllPrefabs[i].name); return(false); } #endif m_PrefabCache.Add(AllPrefabs[i].name, AllPrefabs[i] as GameObject); } return(true); } catch (Exception ex) { CLOG.E(ex.ToString()); return(false); } }
/// <summary> /// 播放处理 /// </summary> /// <returns>协程</returns> private IEnumerator PlayHandler() { while (true) { //CLOG.I( "now play animation={0} index={1} ", Animations[m_NowPlayAnimIndex].AnimState.GetDescription(), m_PlayHeadIndex ); if (m_PlayHeadIndex < 0 || m_PlayHeadIndex >= AnimationData.Frames.Length) { CLOG.E("frame index error!!"); break; } if (m_SR != null) { m_SR.sprite = AnimationData.Frames[m_PlayHeadIndex].SpFrame; } else if (m_Image != null) { m_Image.sprite = AnimationData.Frames[m_PlayHeadIndex].SpFrame; } /************************************************************************/ /* 回调处理 */ /************************************************************************/ if (AnimationData.FrameCallbacks.ContainsKey(m_PlayHeadIndex)) { //如果特定帧回调存在,那么调用它 if (AnimationData.FrameCallbacks[m_PlayHeadIndex] != null) { AnimationData.FrameCallbacks[m_PlayHeadIndex](m_PlayHeadIndex); } } else if (AnimationData.EveryFrameCallback != null) { //如果特定帧回调不存在,而帧回调存在,那么调用帧回调 AnimationData.EveryFrameCallback(m_PlayHeadIndex); } //下一帧 m_PlayHeadIndex++; //安全边界处理 if (m_PlayHeadIndex >= AnimationData.Frames.Length) { if (m_IsLoop) { m_PlayHeadIndex = 0; } else { break; } } yield return(new WaitForSeconds(AnimationData.Frames[m_PlayHeadIndex].SpInteval)); } m_PlayCoroutine = null; m_IsPlaying = false; }
/// <summary> /// 处理收到的包 /// </summary> private void ProcessReceviedPackage() { CMessage message = null; while ((message = m_Receiver.PopReadyToHandlerPackage()) != null) { // 如果是伪造的消息,则创建时会导致读写位置到包的末尾了 // 因此需要在这里重置归0 message.Body.ResetPosition(); // 包ID int OpCode = message.OpCode; // 反射出类型 Type type = CPackageManager.Instance.ReflectionClassNameByActionID(OpCode); //安全处理 if (type == null) { CLOG.E("Reflection class name by OpCode error! OpCode={0} reflection class name = null!! please check the code", OpCode); return; } // 得到该类型的处理委托 DelegatePackageHandler DP = CPackageManager.Instance.GetPackageHandler(type); // 创建反射类型实例 CPackageBase package = Activator.CreateInstance(type) as CPackageBase; //安全处理 if (package == null) { CLOG.E("create package instance error! OpCode = {0} type = {1}", OpCode, type.ToString()); return; } // 从message的身体中获取数据实例化对象 try { package.FromMessage(ref message); } catch (Exception ex) { CLOG.E("from message error! Exception!! OpCode = {0} type={1} message={2} ", OpCode, type.ToString(), message.ToString()); CLOG.E(ex.ToString()); return; } // 调用委托,传入参数 if (DP != null) { DP(package); } else { CLOG.W("ths OpCode {0} was not register handler!", OpCode); } } }
/// <summary> /// 条件满足就中断条件 /// </summary> /// <param name="condition">条件</param> public static void AssertIfFalse(bool condition) { if (condition == false) { CLOG.E("Assest.IsTrue Failed"); } Assert.IsTrue(condition); }
/// <summary> /// 为空就中断条件 /// </summary> /// <param name="obj">条件</param> /// /// <param name="message">消息</param> public static void AssertIfNull(object obj, string message) { if (obj == null) { CLOG.E("{0} is null msg:{1}", obj.ToString(), message); } Assert.IsNotNull(obj, message); }
/// <summary> /// 条件满足就中断条件,抛出文字内容 /// </summary> /// <param name="condition">条件</param> /// <param name="message">消息</param> public static void AssertIfFalse(bool condition, string message) { if (condition == false) { CLOG.E(message); } Assert.IsTrue(condition, message); }
/// <summary> /// 为空就中断条件 /// </summary> /// <param name="obj">条件对象</param> public static void AssertIfNull(object obj) { if (obj == null) { CLOG.E("{0} is null", obj.ToString()); } Assert.IsNotNull(obj); }
/// <summary> /// 直接获得某个孩子身上的指定组件 /// </summary> /// <typeparam name="T">泛型,组件类型</typeparam> /// <param name="target">this扩展</param> /// <param name="ChildName">孩子名字</param> /// <returns></returns> public static T FindChildComponent <T> (this Transform target, string ChildName) { Transform child = target.Find(ChildName); if (child == null) { CLOG.E("in {0} can not find child {1}", target.name, ChildName); return(( T )(System.Object)null); } return(child.GetComponent <T>()); }
/// <summary> /// 添加一个同步任务到队列 /// </summary> /// <param name="Mission"></param> public void Join(CMission Mission) { CMission CM = m_MissionQueue.Last(); if (CM is CMissionHeap) { CM.Join(Mission); } else { CLOG.E("the last mission is not mission heap,so can not join mission to it"); } }
/// <summary> /// 立刻切换到目标场景 /// </summary> /// <param name="TargetScene">目标场景</param> public void ChangeSceneImmediately(string SceneName) { try { CLOG.I("ready to load scene {0} immediate", SceneName); CompleteCallback = null; SceneManager.LoadScene(SceneName, LoadSceneMode.Single); } catch (Exception ex) { CLOG.E((ex.ToString())); } }
/// <summary> /// 缓存一个预制体 /// </summary> /// <param name="name"></param> public bool CachePrefab(string name) { //读取所有预制体 UnityEngine.Object Prefab = Resources.Load(name); #if UNITY_EDITOR if (m_PrefabCache.ContainsKey(Prefab.name)) { CLOG.E("the key {0} has already add to prefab cache", Prefab.name); return(false); } #endif m_PrefabCache.Add(Prefab.name, Prefab as GameObject); return(true); }
/// <summary> /// this扩展,给所有的枚举增加一个ToString方法用来返回特性描述中的值 /// </summary> /// <param name="Target">枚举对象</param> public static string GetDescription(this Enum Target) { try { Type EType = Target.GetType(); string FieldName = Enum.GetName(EType, Target); object[] Attributes = EType.GetField(FieldName).GetCustomAttributes(false); CEnumDesc EnumDisplayAttribute = Attributes.FirstOrDefault((p) => { return(p.GetType().Equals(typeof(CEnumDesc))); }) as CEnumDesc; return(EnumDisplayAttribute == null ? FieldName : EnumDisplayAttribute.Desc); } catch (Exception ex) { CLOG.E(ex.ToString()); return(""); } }
/// <summary> /// 创建UI的界面显示 /// </summary> public static T CreateUI() { Type Tp = typeof(T); // 遍历特性 foreach (var attr in Tp.GetCustomAttributes(false)) { //UI预制体特性 if (attr.GetType() == typeof(CUIInfo)) { return(CreateUI(attr as CUIInfo)); } } CLOG.E("the ui {0} has no CUIInfo attr", typeof(T).ToString()); return(null); }
/// <summary> /// 连接到指定IP和端口 /// </summary> /// <param name="host">ip或者域名</param> /// <param name="port">端口</param> /// <returns></returns> public bool Connect(string host, int port) { m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); string ip = DomainToIP(host); IPAddress ipAddr = IPAddress.Parse(ip); IPEndPoint ipe = new IPEndPoint(ipAddr, port); try { m_Socket.Connect(ipe); return(true); } catch (Exception ex) { CLOG.E(ex.ToString()); return(false); } }
/// <summary> /// 创建UI实例并返回其上的UI组件 /// /// </summary> /// <param name="PrefabName">预制体名</param> /// <param name="NeedAnimation">是否需要动画</param> /// <returns></returns> private static T InstantiateUIAndReturnComponent(CUIInfo UIInfo) { //找当前场景中的画布 GameObject _Canvas = GameObject.Find("Canvas"); if (_Canvas == null) { CLOG.E("now scene has not canvas"); return(null); } //创建UI预制体实例 GameObject CreatedUI = CPrefabManager.Instance.CreatePrefabInstance(UIInfo.PrefabName); if (CreatedUI == null) { CLOG.E("the UI {0} create failed", UIInfo.PrefabName); return(null); } //创建UI界面 CreatedUI.name = UIInfo.PrefabName; RectTransform RT = CreatedUI.GetComponent <RectTransform>(); //设置父节点 CreatedUI.transform.SetParent(_Canvas.transform, false); RT.localScale = Vector3.one; //向UI上添加自身组件 T Ins = GetComponentSafe(CreatedUI); //记录UI信息 Ins.UIInfo = UIInfo; if (UIInfo.IsAnimationUI) { Ins.AnimOnCreate(); } //返回UI实例 return(Ins); }
/// <summary> /// 解密一个数字 /// </summary> /// <param name="number"></param> private int Decryption() { char[] EnStr = _data.ToCharArray(); for (int i = 0; i < EnStr.Length; i++) { EnStr[i] ^= _key_chars[i % _key_chars.Length]; } try { int result = int.Parse(new string ( EnStr )); return(result); } catch (Exception ex) { CLOG.E(ex.ToString()); return(-1); } }
/// <summary> /// 得到数据 /// </summary> /// <returns></returns> public byte[] GetData() { byte[] finalData = new byte[4 + m_BodyLength]; int index = 0; //压入OpCode byte[] data = BitConverter.GetBytes(m_OpCode); finalData[index++] = data[0]; finalData[index++] = data[1]; CLOG.I("Get Data OpCode is {0} {1}", m_OpCode, Convert.ToString(m_OpCode, 2).PadLeft(16, '0')); //压入头长度 data = BitConverter.GetBytes(m_BodyLength); finalData[index++] = data[0]; finalData[index++] = data[1]; CLOG.I("Get Data BodyLength is {0} {1}", m_BodyLength, Convert.ToString(m_BodyLength, 2).PadLeft(16, '0')); //压入身体 data = m_Body.Buffer; if (data.Length < m_BodyLength) { CLOG.E("the ready push body data {0} bytes, but the message object body has only {1} bytes", m_BodyLength, data.Length); return(null); } StringBuilder sb = new StringBuilder(); for (int i = 0; i < m_BodyLength; i++) { finalData[index++] = data[i]; sb.Append(Convert.ToString(data[i], 2).PadLeft(8, '0') + ","); } CLOG.I("Get Data is {0}", sb.ToString()); return(finalData); }
/// <summary> /// 播放动画 /// </summary> /// <param name="IsLoop">是否循环</param> public void PlayAnimation(bool IsLoop = false) { //如果在播放就停止 if (m_IsPlaying) { StopNowAnimation(); } m_IsLoop = IsLoop; //设置播放头为第一帧 m_PlayHeadIndex = 0; int AnimCount = AnimationData.Frames.Length; if (AnimCount > 1) { m_PlayCoroutine = StartCoroutine(PlayHandler()); } else if (AnimCount == 1) { if (m_SR != null) { m_SR.sprite = AnimationData.Frames[0].SpFrame; } else if (m_Image != null) { m_Image.sprite = AnimationData.Frames[0].SpFrame; } } else { CLOG.E("none frame to play!"); return; } m_IsPlaying = true; }
/// <summary> /// 消息发送处理 /// </summary> /// <param name="self">this扩展,this必须是 IMsgSender的实例</param> /// <param name="MsgType">要发送的消息类型</param> /// <param name="paramList">要发送的参数,支持任意类型,任意长度的参数</param> public static void DispatchMessage(this IMsgSender self, ECustomMessageType MsgType, params Object[] paramList) { if (MsgType == ECustomMessageType.NULL) { CLOG.E("error msg type is {0}", MsgType); return; } // 没有注册该消息时的处理 if (!m_MsgHandlerList.ContainsKey(MsgType)) { return; } // 得到所有注册的处理 var Handlers = m_MsgHandlerList[MsgType]; // 得到数量 var HandlerCount = Handlers.Count; // 倒序遍历,防止删除引起的循环异常 for (int i = HandlerCount - 1; i >= 0; i--) { var Handler = Handlers[i]; // 存在处理对象才调用 if (Handler.m_Receiver != null) { Handler.m_Callback(paramList); } else { Handlers.Remove(Handler); } } }
/// <summary> /// 返回收到的数据 /// </summary> /// <returns></returns> private CMessage RecevieData( ) { // 得到Socket对象 Socket _Socket = m_NetworkRef.SocketInstance.Socket; if (_Socket == null || !m_NetworkRef.IsConnected) { return(null); } byte[] Buff = new byte[4]; int length; // 收4个字节的Head try { length = _Socket.Receive(Buff); } catch (Exception ex) { CLOG.V(ex.ToString()); CNetwork.Instance.DisConnect(); return(null); } if (4 != length) { CLOG.V("receive packge length error! length = {0} ", length); return(null); } //取OpCode ushort Opcode = BitConverter.ToUInt16(Buff, 0); //取BodyLength ushort BodyLength = BitConverter.ToUInt16(Buff, 2); //新建包体缓存区 Buff = new byte[BodyLength]; int HasReceivedLength = 0; while (HasReceivedLength < BodyLength) { try { int recSize = _Socket.Receive(Buff, HasReceivedLength, BodyLength - HasReceivedLength, SocketFlags.None); HasReceivedLength += recSize; } catch (Exception ex) { CLOG.V(ex.ToString()); CNetwork.Instance.DisConnect(); //主动断网 return(null); } } CLOG.V("package length is {0} has received {1} data", BodyLength, HasReceivedLength); if (BodyLength != HasReceivedLength || BodyLength != Buff.Length) { CLOG.E("receivce data error!"); return(null); } CMessage message = new CMessage(Opcode, Buff, BodyLength); return(message); }
/// <summary> /// 从body中获取数据,写入参数中去 /// </summary> /// <typeparam name="T">泛型</typeparam> public T PopData <T>(ref CMessage msg) { Type TType = typeof(T); if (TType == typeof(byte)) { return(( T )( Object )PopByte()); } if (TType == typeof(sbyte)) { return(( T )( Object )PopSByte()); } if (TType == typeof(bool)) { return(( T )( Object )PopBoolean()); } if (TType == typeof(short)) { return(( T )( Object )PopShort()); } if (TType == typeof(ushort)) { return(( T )( Object )PopUShort()); } if (TType == typeof(int)) { return(( T )( Object )PopInt()); } if (TType == typeof(uint)) { return(( T )( Object )PopUInt()); } if (TType == typeof(float)) { return(( T )( Object )PopFloat()); } if (TType == typeof(long)) { return(( T )( Object )PopLong()); } if (TType == typeof(ulong)) { return(( T )( Object )PopULong()); } if (TType == typeof(string)) { return(( T )( Object )PopString()); } // 如果反射对象是 CPackageBase 的子类 if (TType.IsSubclassOf(typeof(CPackageBase))) { // 创建反射类型实例 CPackageBase MemberPackageBase = Activator.CreateInstance(TType) as CPackageBase; MemberPackageBase.FromMessage(ref msg); return(( T )( Object )MemberPackageBase); } // 如果反射对象是 List if (TType.IsGenericType) { Type[] GenericTypes = TType.GetGenericArguments(); object[] param = { msg }; return(( T )( Object )CFunction.CallGenericArrayFunction("PopList", this, GenericTypes, param)); } // 如果反射对象是数组 if (TType.IsArray) { Type ElementType = TType.GetElementType(); object[] param = { msg }; return(( T )( Object )CFunction.CallGenericFunction("PopArray", this, ElementType, param)); } CLOG.E("the type {0} has no serilize methon", TType.ToString()); return(default(T)); }
/// <summary> /// Image this扩展,读取图片 /// </summary> /// <param name="image">Imagte组件</param> /// <param name="URL">网络URL头像地址</param> /// <param name="LoadCompleteCallBack">加载完毕回调</param> public static void LoadURLImage(this Image image, string URL, DelegateURLImageLoadComplete LoadCompleteCallBack = null) { if (URL == null || URL == "") { return; } //文件类型 string TargetFileType = GetFileType(URL); //得到文件名 string TargetFileName = GetMD5HeadName(URL) + "." + TargetFileType; //本地文件名,用于判断文件是否存在 string LoacalFileName = Application.persistentDataPath + "/" + TargetFileName; //判断本地文件是否存在 FileInfo FI = new FileInfo(LoacalFileName); //存在就读取本地文件,不存在就读取网络文件 EHttpLocation EHT = FI.Exists ? EHttpLocation.LOCAL : EHttpLocation.REMOTE; //读取完毕回调 DelegateHttpLoadComplete OnComplete = (WWW HttpObj, bool isSuccess) => { try { //加载失败时的回调 if (!isSuccess) { if (LoadCompleteCallBack != null) { LoadCompleteCallBack(isSuccess); } return; } //加载成功,但是头像已销毁 if (image == null) { return; } //得到Texture Texture2D texture = HttpObj.texture; if (texture == null) { return; } //设置Image图片精灵 image.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.zero); //只有远程文件才需要保存 if (EHT == EHttpLocation.REMOTE) { //得到字节流 byte[] ImageData = null; if (TargetFileType == "jpg" || TargetFileType == "jpeg") { ImageData = texture.EncodeToJPG(); } else if (TargetFileType == "png") { ImageData = texture.EncodeToPNG(); } //保存路径 string SaveURl = Application.persistentDataPath + "/" + TargetFileName; CLOG.I("read http remote data complete , Start save image to {0}!", SaveURl); //保存文件 if (ImageData != null) { File.WriteAllBytes(SaveURl, ImageData); } else { CLOG.E("Write file {0} error!", SaveURl); } } //执行回调 if (LoadCompleteCallBack != null) { LoadCompleteCallBack(isSuccess); } } catch (Exception ex) { CLOG.I("********** don't warry it's OK ************"); CLOG.E(ex.ToString()); CLOG.I("*********************************************"); } }; //读取中回调 DelegateHttpLoading OnLoading = null; /* (WWW HttpObj) => * { * * }; */ //创建HTTP加载器 if (EHT == EHttpLocation.REMOTE) { //加载网络头像 CHttp.Instance.CreateHttpLoader(URL, OnComplete, OnLoading, EHT); } else if (EHT == EHttpLocation.LOCAL) { //加载本地文件 CHttp.Instance.CreateHttpLoader(TargetFileName, OnComplete, OnLoading, EHT); } }
/// <summary> /// 压入数据 /// </summary> /// <typeparam name="T">泛型</typeparam> /// <param name="data">要压入的值></param> /// <param name="msg">要压入的目标消息></param> public void PushData <T>(T data, ref CMessage msg) { Type dataType = typeof(T); if (dataType == typeof(byte)) { PushByte(( byte )( Object )data); return; } if (dataType == typeof(sbyte)) { PushByte(( sbyte )( Object )data); return; } if (dataType == typeof(bool)) { PushBoolean(( bool )( Object )data); return; } if (dataType == typeof(int)) { PushInt(( int )( Object )data); return; } if (dataType == typeof(uint)) { PushInt(( uint )( Object )data); return; } if (dataType == typeof(short)) { PushShort(( short )( Object )data); return; } if (dataType == typeof(ushort)) { PushInt(( ushort )( Object )data); return; } if (dataType == typeof(float)) { PushFloat(( float )( Object )data); return; } if (dataType == typeof(long)) { PushLong(( long )( Object )data); return; } if (dataType == typeof(ulong)) { PushLong(( ulong )( Object )data); return; } if (dataType == typeof(string)) { PushString(( string )( Object )data); return; } // 如果反射对象是 CPackageBase 的子类 if (data is CPackageBase) { CPackageBase tempData = ( CPackageBase )( Object )data; if (tempData == null) { return; } tempData.ToMessage(ref msg); return; } // 如果反射对象是 List if (dataType.IsGenericType) { Type[] GenericType = dataType.GetGenericArguments(); object[] param = { data, msg }; CFunction.CallGenericArrayFunction("PushList", this, GenericType, param); return; } // 如果反射对象是数组 if (dataType.IsArray) { Type ElementType = dataType.GetElementType(); object[] param = { data, msg }; CFunction.CallGenericFunction("PushArray", this, ElementType, param); return; } CLOG.E("the type {0} has no serilize methon", dataType.ToString()); }