4 文件已重命名
4个文件已修改
5个文件已删除
24 文件已复制
49个文件已添加
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 4c003e768bc58494b9225ef57ba628ea |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: dc0938f1b84b1c54c8205f7fae9d531c |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | /// <summary> |
| | | /// 战斗对象阵营枚举 |
| | | /// </summary> |
| | | public enum BattleCamp |
| | | { |
| | | Friendly, // 友方 |
| | | Enemy // 敌方 |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 战斗状态枚举 |
| | | /// </summary> |
| | | [Flags] |
| | | public enum BattleState |
| | | { |
| | | None = 0, |
| | | Stunned = 1 << 0, // 眩晕 |
| | | Poisoned = 1 << 1, // 中毒 |
| | | Bleeding = 1 << 2, // 流血 |
| | | Silenced = 1 << 3, // 沉默 |
| | | Frozen = 1 << 4, // 冰冻 |
| | | Burned = 1 << 5 // 灼烧 |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 战斗对象基类 |
| | | /// </summary> |
| | | public class BattleObject |
| | | { |
| | | /// <summary> |
| | | /// 战斗对象ID |
| | | /// </summary> |
| | | public string BattleObjectId { get; protected set; } |
| | | |
| | | /// <summary> |
| | | /// 战斗对象阵营 |
| | | /// </summary> |
| | | public BattleCamp Camp { get; protected set; } = BattleCamp.Friendly; |
| | | |
| | | // Buff系统 |
| | | // List<BuffInfo> buffList; // 所有buff列表 |
| | | // List<BuffInfo> gainBuffList; // 增益buff列表 |
| | | // List<BuffInfo> debuffList; // 减益buff列表 |
| | | |
| | | /// <summary> |
| | | /// 初始化战斗对象 |
| | | /// </summary> |
| | | /// <param name="id">战斗对象ID</param> |
| | | /// <param name="camp">战斗对象阵营</param> |
| | | public virtual void Initialize(string id, BattleCamp camp) |
| | | { |
| | | BattleObjectId = id; |
| | | Camp = camp; |
| | | |
| | | // 初始化Buff列表 |
| | | // buffList = new List<BuffInfo>(); |
| | | // gainBuffList = new List<BuffInfo>(); |
| | | // debuffList = new List<BuffInfo>(); |
| | | } |
| | | |
| | | |
| | | |
| | | #region Buff系统(待实现) |
| | | |
| | | // /// <summary> |
| | | // /// 添加Buff |
| | | // /// </summary> |
| | | // /// <param name="buff">Buff信息</param> |
| | | // public virtual void AddBuff(BuffInfo buff) |
| | | // { |
| | | // // 添加Buff到列表 |
| | | // // 根据Buff类型添加到对应列表 |
| | | // // 应用Buff效果 |
| | | // } |
| | | // |
| | | // /// <summary> |
| | | // /// 移除Buff |
| | | // /// </summary> |
| | | // /// <param name="buffId">Buff ID</param> |
| | | // public virtual void RemoveBuff(string buffId) |
| | | // { |
| | | // // 从列表中移除Buff |
| | | // // 移除Buff效果 |
| | | // } |
| | | // |
| | | // /// <summary> |
| | | // /// 更新所有Buff |
| | | // /// </summary> |
| | | // public virtual void UpdateBuffs() |
| | | // { |
| | | // // 更新所有Buff的持续时间 |
| | | // // 移除已过期的Buff |
| | | // // 应用Buff的持续效果 |
| | | // } |
| | | // |
| | | // /// <summary> |
| | | // /// 获取所有Buff |
| | | // /// </summary> |
| | | // /// <returns>Buff列表</returns> |
| | | // public virtual List<BuffInfo> GetAllBuffs() |
| | | // { |
| | | // return buffList; |
| | | // } |
| | | // |
| | | // /// <summary> |
| | | // /// 获取所有增益Buff |
| | | // /// </summary> |
| | | // /// <returns>增益Buff列表</returns> |
| | | // public virtual List<BuffInfo> GetGainBuffs() |
| | | // { |
| | | // return gainBuffList; |
| | | // } |
| | | // |
| | | // /// <summary> |
| | | // /// 获取所有减益Buff |
| | | // /// </summary> |
| | | // /// <returns>减益Buff列表</returns> |
| | | // public virtual List<BuffInfo> GetDebuffs() |
| | | // { |
| | | // return debuffList; |
| | | // } |
| | | |
| | | #endregion |
| | | |
| | | #region 战斗相关函数 |
| | | |
| | | /// <summary> |
| | | /// 攻击目标 |
| | | /// </summary> |
| | | /// <param name="target">攻击目标</param> |
| | | /// <param name="damage">伤害值</param> |
| | | /// <param name="isCritical">是否暴击</param> |
| | | /// <returns>实际造成的伤害</returns> |
| | | public virtual float AttackTarget(BattleObject target) |
| | | { |
| | | // 子类实现具体逻辑 |
| | | return 0; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 被攻击 |
| | | /// </summary> |
| | | /// <param name="attacker">攻击者</param> |
| | | /// <param name="damage">伤害值</param> |
| | | /// <param name="isCritical">是否暴击</param> |
| | | /// <returns>实际受到的伤害</returns> |
| | | public virtual float UnderAttack(BattleObject attacker) |
| | | { |
| | | // 子类实现具体逻辑 |
| | | return 0; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 治疗目标 |
| | | /// </summary> |
| | | /// <param name="target">治疗目标</param> |
| | | /// <param name="healAmount">治疗量</param> |
| | | /// <param name="isCritical">是否暴击</param> |
| | | /// <returns>实际治疗量</returns> |
| | | public virtual float HealTargets(List<BattleObject> targets) |
| | | { |
| | | // 子类实现具体逻辑 |
| | | return 0; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 被治疗 |
| | | /// </summary> |
| | | /// <param name="healer">治疗者</param> |
| | | /// <param name="healAmount">治疗量</param> |
| | | /// <param name="isCritical">是否暴击</param> |
| | | /// <returns>实际被治疗量</returns> |
| | | public virtual float BeHealed(BattleObject healer, float healAmount) |
| | | { |
| | | // 子类实现具体逻辑 |
| | | return 0; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 复活目标 |
| | | /// </summary> |
| | | /// <param name="target">复活目标</param> |
| | | /// <param name="healthPercent">复活后的生命值百分比</param> |
| | | /// <returns>是否复活成功</returns> |
| | | public virtual bool Revive(BattleObject target) |
| | | { |
| | | // 子类实现具体逻辑 |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 被复活 |
| | | /// </summary> |
| | | /// <param name="reviver">复活者</param> |
| | | /// <param name="healthPercent">复活后的生命值百分比</param> |
| | | /// <returns>是否被复活成功</returns> |
| | | public virtual bool BeRevived(BattleObject reviver, float healthPercent = 0.5f) |
| | | { |
| | | // 子类实现具体逻辑 |
| | | return false; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region 辅助函数 |
| | | |
| | | /// <summary> |
| | | /// 判断是否为敌对关系 |
| | | /// </summary> |
| | | /// <param name="other">其他战斗对象</param> |
| | | /// <returns>是否为敌对关系</returns> |
| | | public virtual bool IsEnemy(BattleObject other) |
| | | { |
| | | if (other == null) return false; |
| | | |
| | | // 不同阵营为敌对关系 |
| | | return Camp != other.Camp; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 判断是否为友好关系 |
| | | /// </summary> |
| | | /// <param name="other">其他战斗对象</param> |
| | | /// <returns>是否为友好关系</returns> |
| | | public virtual bool IsFriendly(BattleObject other) |
| | | { |
| | | if (other == null) return false; |
| | | |
| | | // 相同阵营为友好关系 |
| | | return Camp == other.Camp; |
| | | } |
| | | |
| | | public virtual void Run() |
| | | { |
| | | // 子类实现具体逻辑 |
| | | } |
| | | |
| | | #endregion |
| | | } |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/Battle/BattleObject/BattleObject.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: 585da1d11cf0f484faa41cf4708eaf26 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: ca986d7b9ba51db4f84c00f18ba896b4 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | using Spine.Unity; |
| | | using Cysharp.Threading.Tasks; |
| | | |
| | | /// <summary> |
| | | /// 角色动画基类,处理所有与动画相关的功能 |
| | | /// </summary> |
| | | public class MotionBase |
| | | { |
| | | public class WaitingTask |
| | | { |
| | | public List<int> triggerFrame; |
| | | public MotionName motionName; |
| | | public int currentFrame; |
| | | public Action<MotionName, int> callback; |
| | | |
| | | public WaitingTask(List<int> triggerFrame, MotionName motionName, Action<MotionName, int> _callback) |
| | | { |
| | | this.triggerFrame = triggerFrame; |
| | | this.motionName = motionName; |
| | | this.currentFrame = 0; |
| | | this.callback = _callback; |
| | | } |
| | | |
| | | public bool IsFinished() |
| | | { |
| | | return triggerFrame.Count <= 0; |
| | | } |
| | | |
| | | public void Run() |
| | | { |
| | | if (triggerFrame.Count > 0) |
| | | { |
| | | currentFrame ++; |
| | | |
| | | if (currentFrame >= triggerFrame[0]) |
| | | { |
| | | triggerFrame.RemoveAt(0); |
| | | callback?.Invoke(motionName, currentFrame); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 动画事件 |
| | | public Action OnAttackAnimationComplete; |
| | | public Action OnHitAnimationComplete; |
| | | public Action<int> OnAttackHitEvent; //trigger index |
| | | |
| | | #region 组件引用 |
| | | |
| | | protected SkeletonGraphic skeletonGraphic; |
| | | protected Spine.AnimationState spineAnimationState; |
| | | protected Spine.Skeleton skeleton; |
| | | |
| | | #endregion |
| | | |
| | | #region 动画设置 |
| | | |
| | | // 动画混合时间 |
| | | protected float defaultMixDuration = 0.2f; |
| | | |
| | | #endregion |
| | | |
| | | protected List<WaitingTask> waitingTaskList = new List<WaitingTask>(); |
| | | protected List<WaitingTask> removeList = new List<WaitingTask>(); |
| | | |
| | | #region 初始化方法 |
| | | |
| | | /// <summary> |
| | | /// 初始化动画组件 |
| | | /// </summary> |
| | | /// <param name="skeletonGraphic">骨骼动画组件</param> |
| | | public virtual void Initialize(SkeletonGraphic skeletonGraphic) |
| | | { |
| | | this.skeletonGraphic = skeletonGraphic; |
| | | |
| | | if (skeletonGraphic != null) |
| | | { |
| | | spineAnimationState = skeletonGraphic.AnimationState; |
| | | skeleton = skeletonGraphic.Skeleton; |
| | | |
| | | // 设置动画混合时间 |
| | | if (spineAnimationState != null) |
| | | { |
| | | spineAnimationState.Data.DefaultMix = defaultMixDuration; |
| | | } |
| | | |
| | | // 播放默认动画 |
| | | PlayAnimation(MotionName.idle, true); |
| | | |
| | | // 设置动画事件监听 |
| | | SetupAnimationHandlers(); |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("缺少SkeletonGraphic组件!"); |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region 动画控制 |
| | | |
| | | /// <summary> |
| | | /// 播放指定动画 |
| | | /// </summary> |
| | | /// <param name="motionName">动画枚举</param> |
| | | /// <param name="loop">是否循环</param> |
| | | /// <returns>动画轨道条目</returns> |
| | | public virtual Spine.TrackEntry PlayAnimation(MotionName motionName, bool loop) |
| | | { |
| | | if (spineAnimationState == null) return null; |
| | | |
| | | // 直接使用 ToString() 而不是调用 GetAnimationName |
| | | return spineAnimationState.SetAnimation(0, motionName.ToString(), loop); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 播放指定动画(使用字符串名称) |
| | | /// </summary> |
| | | /// <param name="animationName">动画名称</param> |
| | | /// <param name="loop">是否循环</param> |
| | | /// <returns>动画轨道条目</returns> |
| | | public virtual Spine.TrackEntry PlayAnimation(string animationName, bool loop) |
| | | { |
| | | if (spineAnimationState == null) return null; |
| | | |
| | | return spineAnimationState.SetAnimation(0, animationName, loop); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 添加动画到队列 |
| | | /// </summary> |
| | | /// <param name="motionName">动画枚举</param> |
| | | /// <param name="loop">是否循环</param> |
| | | /// <param name="delay">延迟时间</param> |
| | | /// <returns>动画轨道条目</returns> |
| | | public virtual Spine.TrackEntry AddAnimation(MotionName motionName, bool loop, float delay) |
| | | { |
| | | if (spineAnimationState == null) return null; |
| | | |
| | | // 直接使用 ToString() 而不是调用 GetAnimationName |
| | | return spineAnimationState.AddAnimation(0, motionName.ToString(), loop, delay); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 添加动画到队列(使用字符串名称) |
| | | /// </summary> |
| | | /// <param name="animationName">动画名称</param> |
| | | /// <param name="loop">是否循环</param> |
| | | /// <param name="delay">延迟时间</param> |
| | | /// <returns>动画轨道条目</returns> |
| | | public virtual Spine.TrackEntry AddAnimation(string animationName, bool loop, float delay) |
| | | { |
| | | if (spineAnimationState == null) return null; |
| | | |
| | | return spineAnimationState.AddAnimation(0, animationName, loop, delay); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置动画事件监听 |
| | | /// </summary> |
| | | protected virtual void SetupAnimationHandlers() |
| | | { |
| | | if (spineAnimationState == null) return; |
| | | |
| | | // 监听动画完成事件 |
| | | spineAnimationState.Complete += OnAnimationComplete; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 动画完成事件处理 |
| | | /// </summary> |
| | | protected virtual void OnAnimationComplete(Spine.TrackEntry trackEntry) |
| | | { |
| | | string animation = trackEntry.Animation.Name; |
| | | |
| | | // 攻击动画完成后恢复到待机状态 |
| | | if (animation == MotionName.atk1.ToString() || |
| | | animation == MotionName.atk2.ToString()) |
| | | { |
| | | OnAttackAnimationComplete?.Invoke(); |
| | | PlayAnimation(MotionName.idle, true); |
| | | } |
| | | // 受伤动画完成后恢复到待机状态 |
| | | else if (animation == MotionName.hit.ToString()) |
| | | { |
| | | OnHitAnimationComplete?.Invoke(); |
| | | PlayAnimation(MotionName.idle, true); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 动画事件处理 |
| | | /// </summary> |
| | | protected virtual void OnTriggerHitEvent(MotionName motionName, int hitIndex) |
| | | { |
| | | OnAttackHitEvent?.Invoke(hitIndex); |
| | | } |
| | | |
| | | // 拓展了播放动画方法,添加了触发帧的功能,在攻击动画中多段攻击的触发帧 |
| | | // 例如:攻击动画有三段,第一段攻击在第1帧触发,第二段攻击在第10帧触发,第三段攻击在第20帧触发 |
| | | // 那么triggerFrame就应该是[1, 10, 20] |
| | | public virtual void PlayAnimationEx(MotionName motionName, bool loop, List<int> triggerFrame = null) |
| | | { |
| | | PlayAnimation(motionName, loop); |
| | | if (triggerFrame != null && triggerFrame.Count >= 0) |
| | | { |
| | | AddWaitingTask(triggerFrame, motionName); |
| | | } |
| | | } |
| | | |
| | | protected void AddWaitingTask(List<int> triggerFrame, MotionName motionName) |
| | | { |
| | | if (triggerFrame != null && triggerFrame.Count > 0) |
| | | { |
| | | WaitingTask waitingTask = new WaitingTask(triggerFrame, motionName, OnTriggerHitEvent); |
| | | waitingTaskList.Add(waitingTask); |
| | | } |
| | | } |
| | | |
| | | public virtual void Run() |
| | | { |
| | | foreach (WaitingTask waitingTask in waitingTaskList) |
| | | { |
| | | waitingTask.Run(); |
| | | |
| | | if (waitingTask.IsFinished()) |
| | | { |
| | | removeList.Add(waitingTask); |
| | | } |
| | | } |
| | | |
| | | foreach (WaitingTask waitingTask in removeList) |
| | | { |
| | | waitingTaskList.Remove(waitingTask); |
| | | } |
| | | |
| | | removeList.Clear(); |
| | | } |
| | | #endregion |
| | | |
| | | } |
New file |
| | |
| | | |
| | | |
| | | public enum MotionName |
| | | { |
| | | atk1, |
| | | atk2, |
| | | hit, |
| | | idle, |
| | | run, |
| | | } |
File was renamed from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: 88b8611ab751dba40a16159f3d2fcbcb |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: ec4bdc5ff35cf96419554a0e46696eb6 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | |
| | | |
| | | public partial class CardInfo |
| | | { |
| | | // 战斗属性的触发几率计算是1对1的,可同时触发多个属性且多次触发,触发几率不会随着目标数量多少而改变,只会根据同一目标的触发次数增多而降低。 |
| | | // 即在一回合内,同一个目标反击、连击、击晕、暴击、闪避可以同时并多次触发,触发几率随机触发次数的增加而降低,每个属性开公式来(参数:触发几率、抵抗几率、已触发次数) |
| | | // 优先判断是否命中,必中后同时判断此次攻击是否连击、击晕、暴击生效 |
| | | // 反击时必命中目标 |
| | | // 武将属性需时时计算,根据技能、BUFF、装备等属性来源改变而改变 |
| | | |
| | | |
| | | //战斗属性 |
| | | //闪避概率 |
| | | public float dodge = 0f; |
| | | //暴击概率 |
| | | public float crit = 0f; |
| | | //连击概率 |
| | | public float comboRate = 0f; |
| | | //眩晕概率 |
| | | public float stunRate = 0f; |
| | | //反击概率 |
| | | public float counterAttack = 0f; |
| | | //攻击目标时,造成伤害转化成生命的百分比数值提升 |
| | | public float recoverRate = 0f; |
| | | |
| | | //战斗抵抗属性 |
| | | //闪避抵抗 |
| | | public float dodgeResist = 0f; |
| | | //暴击抵抗 |
| | | public float critResist = 0f; |
| | | //连击抵抗 |
| | | public float comboResist = 0f; |
| | | //眩晕抵抗 |
| | | public float stunResist = 0f; |
| | | //反击抵抗 |
| | | public float counterAttackResist = 0f; |
| | | //减少攻击时吸血转化成生命的百分比数值 |
| | | public float recoverResist = 0f; |
| | | |
| | | //计算个人/职业/种族养成属性加成 |
| | | public void CalculateProperties() |
| | | { |
| | | //todo |
| | | } |
| | | |
| | | public int CalculatePower() |
| | | { |
| | | //todo |
| | | return 0; |
| | | } |
| | | } |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/Card/CardInfo.Properties.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: 8b30e11e231880d45a28598cef7b63f5 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | public partial class CardInfo |
| | | { |
| | | public long sid; |
| | | |
| | | public int cardId; |
| | | |
| | | public int cardLevel; |
| | | |
| | | public int cardStar; |
| | | |
| | | public int breakLevel; |
| | | |
| | | // public List<int> cardEquipList; |
| | | |
| | | // public List<int> cardRuneList; |
| | | |
| | | // public List<int> cardMedalList; |
| | | |
| | | // public CardConfig cardConfig; |
| | | |
| | | public CardSkillMgr cardSkillMgr; |
| | | |
| | | public CardInfo(/*TODO 等待服务器数据*/) |
| | | { |
| | | cardSkillMgr = new CardSkillMgr(this); |
| | | } |
| | | |
| | | |
| | | } |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/Card/CardInfo.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: 1a586a3dd13cc774fadc7b2129a8c885 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | using Cysharp.Threading.Tasks; |
| | | |
| | | /// <summary> |
| | | /// 角色技能管理器,处理所有与技能相关的功能 |
| | | /// </summary> |
| | | public class CardSkillMgr |
| | | { |
| | | public CardInfo cardInfo; |
| | | |
| | | public CardSkillMgr(CardInfo _cardInfo) |
| | | { |
| | | this.cardInfo = _cardInfo; |
| | | |
| | | Init(); |
| | | } |
| | | |
| | | public void Init() |
| | | { |
| | | |
| | | } |
| | | } |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/Card/CardSkillMgr.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: 97462d62c358e0a41a1ba6d83d821ad4 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | |
| | | public enum CardType |
| | | { |
| | | Wei, // 魏 |
| | | Shu, // 蜀 |
| | | Wu, // 吴 |
| | | Shen, // 神 |
| | | Mo, // 魔 |
| | | } |
| | | |
| | | // 上阵4名指定国武将可激活 生命+10% 攻击+10%,激活后相应词条亮起与对应图标修改。 |
| | | // 上阵5名指定国武将可激活 生命+15% 攻击+15%,激活后相应词条亮起与对应图标修改。 |
| | | // 上阵6名指定国武将可激活 生命+20% 攻击+20%,激活后相应词条亮起与对应图标修改。 |
| | | // 属性数值需要支持配置 |
| | | // 阵营颜色:魏国:蓝、吴国:红色、蜀国:绿色、神:黄色、魔:暗紫 |
| | | // 当满足多条词条时,只有最高属性词条生效并修改成对应图标显示 |
| | | // 根据上阵武将情况时时修改阵营光环图标并激活对应词条 |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/Card/CardType.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: 52648f1b5c66b3b41b7654ff65f1b2b0 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | using System; |
| | | |
| | | public class FieldPrint |
| | | { |
| | | |
| | | public static string PrintFields(object _object) |
| | | { |
| | | if (_object == null) |
| | | { |
| | | return string.Empty; |
| | | } |
| | | |
| | | var fields = _object.GetType().GetFields(); |
| | | var contents = new string[fields.Length]; |
| | | for (int i = 0; i < fields.Length; i++) |
| | | { |
| | | var field = fields[i]; |
| | | var fieldContent = field.GetValue(_object); |
| | | contents[i] = string.Format("\"{0}\":{1}", field.Name, fieldContent); |
| | | } |
| | | |
| | | return string.Join("; ", contents); |
| | | } |
| | | |
| | | public static List<string> PrintFieldsExpand(object _object, bool _includeArray) |
| | | { |
| | | if (_object == null) |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | var fields = _object.GetType().GetFields(); |
| | | var contents = new List<string>(); |
| | | for (int i = 0; i < fields.Length; i++) |
| | | { |
| | | var field = fields[i]; |
| | | var fieldContent = field.GetValue(_object); |
| | | if (fieldContent is Array) |
| | | { |
| | | contents.AddRange(PrintArray(field.Name, fieldContent)); |
| | | } |
| | | else |
| | | { |
| | | contents.Add(string.Format("\"{0}\":{1}", field.Name, fieldContent)); |
| | | } |
| | | } |
| | | |
| | | return contents; |
| | | } |
| | | |
| | | private static string[] PrintArray(string _name, object _object) |
| | | { |
| | | var objects = _object as Array; |
| | | var contents = new string[objects.Length]; |
| | | for (int i = 0; i < objects.Length; i++) |
| | | { |
| | | var o = objects.GetValue(i); |
| | | var type = o.GetType(); |
| | | |
| | | if (type.Name == "String") |
| | | { |
| | | contents[i] = string.Format("\"{0}\"[{1}]-->({2}){3}", _name, i, type.Name, (String)o); |
| | | } |
| | | else if (type.Name == "UInt32") |
| | | { |
| | | contents[i] = string.Format("\"{0}\"[{1}]-->({2}){3}", _name, i, type.Name, (UInt32)o); |
| | | } |
| | | else if (type.Name == "Byte") |
| | | { |
| | | contents[i] = string.Format("\"{0}\"[{1}]-->({2}){3}", _name, i, type.Name, (Byte)o); |
| | | } |
| | | else if (type.Name == "UInt16") |
| | | { |
| | | contents[i] = string.Format("\"{0}\"[{1}]-->({2}){3}", _name, i, type.Name, (UInt16)o); |
| | | } |
| | | else if (type.Name == "Single") |
| | | { |
| | | contents[i] = string.Format("\"{0}\"[{1}]-->({2}){3}", _name, i, type.Name, (float)o); |
| | | } |
| | | else if (type.Name == "Boolean") |
| | | { |
| | | contents[i] = string.Format("\"{0}\"[{1}]-->({2}){3}", _name, i, type.Name, (bool)o); |
| | | } |
| | | else if (type.Name == "Int32") |
| | | { |
| | | contents[i] = string.Format("\"{0}\"[{1}]-->({2}){3}", _name, i, type.Name, (int)o); |
| | | } |
| | | else |
| | | { |
| | | contents[i] = string.Format("\"{0}\"[{1}]-->{2}", _name, i, PrintFields(o)); |
| | | } |
| | | } |
| | | |
| | | return contents; |
| | | } |
| | | |
| | | } |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/Common/FieldPrint.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: e8426254dd294aa428e2078f8e48cd5e |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2025年5月13日 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System.Threading; |
| | | using System; |
| | | using UnityEngine; |
| | | using LitJson; |
| | | |
| | | public partial class FamilyConfig : ConfigBase<int, FamilyConfig> |
| | | { |
| | | |
| | | public int familyLV; |
| | | public int memberCnt; |
| | | public int deputyLeaderCnt; |
| | | public int eliteCnt; |
| | | public int needMoney; |
| | | public int weekMissionMoneyMax; |
| | | public int bossFBCnt; |
| | | public int ZhenbaogeWeights; |
| | | |
| | | public override int LoadKey(string _key) |
| | | { |
| | | int key = GetKey(_key); |
| | | return key; |
| | | } |
| | | |
| | | public override void LoadConfig(string input) |
| | | { |
| | | string[] tables = input.Split('\t'); |
| | | int.TryParse(tables[0],out familyLV); |
| | | |
| | | int.TryParse(tables[1],out memberCnt); |
| | | |
| | | int.TryParse(tables[2],out deputyLeaderCnt); |
| | | |
| | | int.TryParse(tables[3],out eliteCnt); |
| | | |
| | | int.TryParse(tables[4],out needMoney); |
| | | |
| | | int.TryParse(tables[5],out weekMissionMoneyMax); |
| | | |
| | | int.TryParse(tables[6],out bossFBCnt); |
| | | |
| | | int.TryParse(tables[7],out ZhenbaogeWeights); |
| | | } |
| | | } |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/Config/Configs/FamilyConfig.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: 3aa8bbc93ccbf0348ae003e053029d7f |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 8d0fec473a0754742863776bae15b005 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | // 初始化游戏系统
|
| | | managers.Add(PlaceManager.Instance);
|
| | | managers.Add(BattleManager.Instance);
|
| | | managers.Add(TeamManager.Instance);
|
| | |
|
| | | foreach (var manager in managers)
|
| | | {
|
| | |
| | | isLoadFinished = false;
|
| | |
|
| | | // 加载配置文件
|
| | | int totalConfigs = 1;
|
| | | Type[] configTypes = new Type[] {
|
| | | typeof(FamilyConfig)
|
| | | };
|
| | |
|
| | | // 逐个加载配置并更新进度
|
| | | for (int i = 0; i < configTypes.Length; i++)
|
| | | {
|
| | | await LoadConfigByType(configTypes[i]);
|
| | | loadingProgress = (float)(i + 1) / totalConfigs;
|
| | | }
|
| | |
|
| | | // 加载完成后设置isLoadFinished为true
|
| | | loadingProgress = 1f;
|
| | |
| | | Debug.LogError($"找不到配置文件: {configName}");
|
| | | }
|
| | | }
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | | private async UniTask LoadConfig<T>() where T : class
|
| | | {
|
| | |
| | |
|
| | | public override void Release()
|
| | | {
|
| | | // 没有找到配置类
|
| | | // 清空 FamilyConfig 字典
|
| | | ClearConfigDictionary<FamilyConfig>();
|
| | | }
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | | } |
| | | }
|
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 5e5b6f2644a590642aa1697217e1cdf4 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using System; |
| | | using UnityEngine; |
| | | using System.Collections.Generic; |
| | | using UnityEngine.Events; |
| | | using StartAot; |
| | | |
| | | public class Clock |
| | | { |
| | | public bool stopped { get; set; } |
| | | DateTime alarmTime; |
| | | UnityAction alarmCallBack; |
| | | |
| | | public Clock(DateTime alarmTime, UnityAction callBack) |
| | | { |
| | | this.alarmTime = alarmTime; |
| | | this.alarmCallBack = callBack; |
| | | } |
| | | |
| | | public bool CanAlarm() |
| | | { |
| | | return DateTime.Now >= alarmTime; |
| | | } |
| | | |
| | | public void Execute() |
| | | { |
| | | if (alarmCallBack != null) |
| | | { |
| | | alarmCallBack(); |
| | | alarmCallBack = null; |
| | | } |
| | | } |
| | | |
| | | static List<Clock> clocks = new List<Clock>(); |
| | | |
| | | public static void Init() |
| | | { |
| | | new LogicUpdate().Start(OnUpdate); |
| | | } |
| | | |
| | | public static Clock AlarmAt(DateTime alarmTime, UnityAction callBack) |
| | | { |
| | | var clock = new Clock(alarmTime, callBack); |
| | | |
| | | clocks.Add(clock); |
| | | return clock; |
| | | } |
| | | |
| | | public static Clock AlarmAfter(double seconds, UnityAction callBack) |
| | | { |
| | | var clock = new Clock(DateTime.Now.AddSeconds(seconds), callBack); |
| | | |
| | | clocks.Add(clock); |
| | | return clock; |
| | | } |
| | | |
| | | public static void Stop(Clock clock) |
| | | { |
| | | if (clocks.Contains(clock)) |
| | | { |
| | | clock.stopped = true; |
| | | } |
| | | } |
| | | |
| | | static void OnUpdate() |
| | | { |
| | | for (var i = clocks.Count - 1; i >= 0; i--) |
| | | { |
| | | var clock = clocks[i]; |
| | | if (clock.stopped) |
| | | { |
| | | clocks.RemoveAt(i); |
| | | continue; |
| | | } |
| | | |
| | | if (clock.CanAlarm()) |
| | | { |
| | | try |
| | | { |
| | | clock.Execute(); |
| | | clocks.RemoveAt(i); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | Debug.LogException(e); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/NetworkPackage/Clock.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: 7122809994ef46c4a876e823b99c2473 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: d31cd6caeeca0034bac8394eb2571a2a |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | public class AccountLoginState : NetState |
| | | { |
| | | const int OVERTIME_THRESHOLD = 15; |
| | | float overTime = 0f; |
| | | |
| | | public override void OnEnter() |
| | | { |
| | | base.OnEnter(); |
| | | overTime = Time.time + OVERTIME_THRESHOLD; |
| | | } |
| | | |
| | | protected override void Update() |
| | | { |
| | | if (GameNetSystem.Instance.netState != GameNetSystem.NetState.AccountLogin) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | if (Time.time > overTime) |
| | | { |
| | | GameNetSystem.Instance.LoginOut(); |
| | | // ServerForceExitHintWin.reason = 111; |
| | | } |
| | | } |
| | | |
| | | public override void OnExit() |
| | | { |
| | | base.OnExit(); |
| | | } |
| | | |
| | | } |
copy from Utility/StringUtility.cs.meta
copy to Main/NetworkPackage/DataToCtl/AccountLoginState.cs.meta
File was copied from Utility/StringUtility.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: c0960ed66238bdd49b70860dfee23488 |
| | | timeCreated: 1475005527 |
| | | licenseType: Free |
| | | guid: f5abaa5b8abbec948a68390b75c55a90 |
| | | timeCreated: 1519302320 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
New file |
| | |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | using System; |
| | | |
| | | public class ConnectedState : NetState |
| | | { |
| | | |
| | | const int OVERTIME_THRESHOLD = 20; |
| | | |
| | | bool connectedDetecting = false; |
| | | |
| | | NetworkReachability m_NetWorkReachability = NetworkReachability.ReachableViaCarrierDataNetwork; |
| | | NetworkReachability netWorkReachability { |
| | | get { return m_NetWorkReachability; } |
| | | set { |
| | | if (m_NetWorkReachability != value) |
| | | { |
| | | m_NetWorkReachability = value; |
| | | DetectConnected(3); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public override void OnEnter() |
| | | { |
| | | base.OnEnter(); |
| | | |
| | | m_NetWorkReachability = Application.internetReachability; |
| | | // NetLinkWin.Hide(); |
| | | } |
| | | |
| | | protected override void Update() |
| | | { |
| | | if (GameNetSystem.Instance.netState != GameNetSystem.NetState.Connected) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | if (connectedDetecting) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | if (GameNetSystem.Instance.timeSinceMainSocketLastProtocol > OVERTIME_THRESHOLD |
| | | || (GameNetSystem.Instance.crossServerConnected_Loigc && GameNetSystem.Instance.timeSinceCrossServerSocketLastProtocol > OVERTIME_THRESHOLD)) |
| | | { |
| | | DetectConnected(3); |
| | | } |
| | | else if (!GameNetSystem.Instance.mainSocketConnected |
| | | || (GameNetSystem.Instance.crossServerConnected_Loigc && !GameNetSystem.Instance.crossServerSocketConnected)) |
| | | { |
| | | DetectConnected(3); |
| | | } |
| | | else |
| | | { |
| | | #if UNITY_IOS && !UNITY_EDITOR |
| | | netWorkReachability = Application.internetReachability; |
| | | #endif |
| | | } |
| | | } |
| | | |
| | | Clock clock; |
| | | |
| | | public override void OnExit() |
| | | { |
| | | if (clock != null) |
| | | { |
| | | Clock.Stop(clock); |
| | | } |
| | | clock = null; |
| | | |
| | | base.OnExit(); |
| | | } |
| | | |
| | | private void DetectConnected(int _seconds) |
| | | { |
| | | connectedDetecting = true; |
| | | |
| | | // var sendInfo1 = new C0104_tagCOnlineReturn(); |
| | | // sendInfo1.Type = 0; |
| | | // GameNetSystem.Instance.SendInfo(sendInfo1);// 在线回应 |
| | | |
| | | // if (GameNetSystem.Instance.crossServerConnected_Loigc) |
| | | // { |
| | | // var sendInfo2 = new C0104_tagCOnlineReturn(); |
| | | // sendInfo2.Type = 0; |
| | | // GameNetSystem.Instance.SendToCrossServer(sendInfo2);// 在线回应 |
| | | // } |
| | | |
| | | // if (clock != null) |
| | | // { |
| | | // Clock.Stop(clock); |
| | | // } |
| | | // clock = Clock.AlarmAt(DateTime.Now + new TimeSpan(_seconds * TimeSpan.TicksPerSecond), OnDetectEnd); |
| | | } |
| | | |
| | | private void OnDetectEnd() |
| | | { |
| | | connectedDetecting = false; |
| | | |
| | | var isDisconnected = false; |
| | | #if UNITY_IOS && !UNITY_EDITOR |
| | | isDisconnected = GameNetSystem.Instance.timeSinceMainSocketLastProtocol > 3f; |
| | | #else |
| | | isDisconnected = !GameNetSystem.Instance.mainSocketConnected |
| | | || GameNetSystem.Instance.timeSinceMainSocketLastProtocol > OVERTIME_THRESHOLD; |
| | | #endif |
| | | |
| | | if (GameNetSystem.Instance.crossServerConnected_Loigc) |
| | | { |
| | | #if UNITY_IOS && !UNITY_EDITOR |
| | | isDisconnected = isDisconnected || GameNetSystem.Instance.timeSinceCrossServerSocketLastProtocol > 3f; |
| | | #else |
| | | isDisconnected = isDisconnected || !GameNetSystem.Instance.crossServerSocketConnected |
| | | || GameNetSystem.Instance.timeSinceCrossServerSocketLastProtocol > OVERTIME_THRESHOLD; |
| | | #endif |
| | | } |
| | | |
| | | if (isDisconnected) |
| | | { |
| | | switch (Application.internetReachability) |
| | | { |
| | | case NetworkReachability.NotReachable: |
| | | GameNetSystem.Instance.Disconnect(); |
| | | // WindowCenter.Instance.Open<DisconnectHintWin>(); |
| | | break; |
| | | case NetworkReachability.ReachableViaCarrierDataNetwork: |
| | | case NetworkReachability.ReachableViaLocalAreaNetwork: |
| | | GameNetSystem.Instance.Reconnect(); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void OnApplicationPause(bool pause) |
| | | { |
| | | if (GameNetSystem.Instance.netState != GameNetSystem.NetState.Connected) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | if (!pause) |
| | | { |
| | | DetectConnected(3); |
| | | } |
| | | } |
| | | |
| | | } |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/NetworkPackage/DataToCtl/ConnectedState.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: 0c7c606c8fec2ad4b8463a33d2673213 |
| | | timeCreated: 1519302351 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
New file |
| | |
| | | // using System.Collections; |
| | | // using System.Collections.Generic; |
| | | // using UnityEngine; |
| | | // using System; |
| | | |
| | | // public class CreateOrSelectRoleState : NetState |
| | | // { |
| | | // const int OVERTIME_THRESHOLD = 12; |
| | | // bool connectedDetecting = false; |
| | | |
| | | // NetworkReachability m_NetWorkReachability = NetworkReachability.ReachableViaCarrierDataNetwork; |
| | | // NetworkReachability netWorkReachability { |
| | | // get { return m_NetWorkReachability; } |
| | | // set { |
| | | // if (m_NetWorkReachability != value) |
| | | // { |
| | | // m_NetWorkReachability = value; |
| | | // DetectConnected(3); |
| | | // } |
| | | // } |
| | | // } |
| | | |
| | | // public override void OnEnter() |
| | | // { |
| | | // m_NetWorkReachability = Application.internetReachability; |
| | | // // NetLinkWin.Hide(); |
| | | // base.OnEnter(); |
| | | // } |
| | | |
| | | // protected override void Update() |
| | | // { |
| | | // if (GameNetSystem.Instance.netState != GameNetSystem.NetState.CreateOrSelectRole) |
| | | // { |
| | | // return; |
| | | // } |
| | | |
| | | // if (connectedDetecting) |
| | | // { |
| | | // return; |
| | | // } |
| | | |
| | | // if (GameNetSystem.Instance.timeSinceMainSocketLastProtocol > OVERTIME_THRESHOLD) |
| | | // { |
| | | // DetectConnected(3); |
| | | // } |
| | | // else if (!GameNetSystem.Instance.mainSocketConnected) |
| | | // { |
| | | // DetectConnected(3); |
| | | // } |
| | | // else |
| | | // { |
| | | // #if UNITY_IOS && !UNITY_EDITOR |
| | | // netWorkReachability = Application.internetReachability; |
| | | // #endif |
| | | // } |
| | | // } |
| | | |
| | | // public override void OnExit() |
| | | // { |
| | | // if (clock != null) |
| | | // { |
| | | // Clock.Stop(clock); |
| | | // } |
| | | // clock = null; |
| | | // base.OnExit(); |
| | | // } |
| | | |
| | | // Clock clock; |
| | | // private void DetectConnected(int _seconds) |
| | | // { |
| | | // connectedDetecting = true; |
| | | |
| | | // var sendInfo = new C0104_tagCOnlineReturn(); |
| | | // sendInfo.Type = 0; |
| | | // GameNetSystem.Instance.SendInfo(sendInfo);// 在线回应 |
| | | |
| | | // if (clock != null) |
| | | // { |
| | | // Clock.Stop(clock); |
| | | // } |
| | | // clock = Clock.AlarmAt(DateTime.Now + new TimeSpan(_seconds * TimeSpan.TicksPerSecond), OnDetectEnd); |
| | | // } |
| | | |
| | | // private void OnDetectEnd() |
| | | // { |
| | | // connectedDetecting = false; |
| | | |
| | | // var isDisconnected = false; |
| | | // #if UNITY_IOS && !UNITY_EDITOR |
| | | // isDisconnected = GameNetSystem.Instance.timeSinceMainSocketLastProtocol > 3f; |
| | | // #else |
| | | // isDisconnected = !GameNetSystem.Instance.mainSocketConnected |
| | | // || GameNetSystem.Instance.timeSinceMainSocketLastProtocol > OVERTIME_THRESHOLD; |
| | | // #endif |
| | | |
| | | // if (isDisconnected) |
| | | // { |
| | | // switch (Application.internetReachability) |
| | | // { |
| | | // case NetworkReachability.NotReachable: |
| | | // GameNetSystem.Instance.Disconnect(); |
| | | // WindowCenter.Instance.Open<DisconnectHintWin>(); |
| | | // break; |
| | | // case NetworkReachability.ReachableViaCarrierDataNetwork: |
| | | // case NetworkReachability.ReachableViaLocalAreaNetwork: |
| | | // GameNetSystem.Instance.Reconnect(); |
| | | // break; |
| | | // } |
| | | // } |
| | | // } |
| | | |
| | | // private void OnApplicationPause(bool pause) |
| | | // { |
| | | // if (GameNetSystem.Instance.netState != GameNetSystem.NetState.CreateOrSelectRole) |
| | | // { |
| | | // return; |
| | | // } |
| | | |
| | | // if (!pause) |
| | | // { |
| | | // DetectConnected(3); |
| | | // } |
| | | // } |
| | | |
| | | // } |
copy from Utility/StringUtility.cs.meta
copy to Main/NetworkPackage/DataToCtl/CreateOrSelectRoleState.cs.meta
File was copied from Utility/StringUtility.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: c0960ed66238bdd49b70860dfee23488 |
| | | timeCreated: 1475005527 |
| | | licenseType: Free |
| | | guid: 903872d42f3a20149883eac95f2b5c80 |
| | | timeCreated: 1519307260 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 679cd6ab06f24164bbd2bfd2060ee0bb |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | |
| | | /** 数据转逻辑处理的基类 */ |
| | | public class DtcBasic { |
| | | |
| | | /** 最近一次触发数据包处理的时刻 */ |
| | | // protected float _lastDoneTime = 0; |
| | | |
| | | /** 继承类需要重写的方法,一般仅改变数据层,但也充许直接操作对象,如有必要 */ |
| | | public virtual void Done(GameNetPackBasic vNetPack) { |
| | | // _lastDoneTime = Time.time; // 由于是非主线程,所以不能使用 Time |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 02cde0a61d95dc34fa677099daf7d232 |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
New file |
| | |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | public class DisconnectState : NetState |
| | | { |
| | | |
| | | public override void OnEnter() |
| | | { |
| | | base.OnEnter(); |
| | | |
| | | // NetLinkWin.Hide(); |
| | | } |
| | | |
| | | protected override void Update() |
| | | { |
| | | if (GameNetSystem.Instance.netState != GameNetSystem.NetState.DisConnected) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | } |
| | | |
| | | public override void OnExit() |
| | | { |
| | | base.OnExit(); |
| | | } |
| | | |
| | | |
| | | } |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/NetworkPackage/DataToCtl/DisconnectState.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: 441d0f42949286a47af2e4046c225f9b |
| | | timeCreated: 1519302373 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
New file |
| | |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | public class NetState : MonoBehaviour |
| | | { |
| | | |
| | | private void Awake() |
| | | { |
| | | enabled = false; |
| | | } |
| | | |
| | | public virtual void OnEnter() |
| | | { |
| | | enabled = true; |
| | | } |
| | | |
| | | protected virtual void Update() |
| | | { |
| | | |
| | | } |
| | | |
| | | public virtual void OnExit() |
| | | { |
| | | enabled = false; |
| | | } |
| | | } |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/NetworkPackage/DataToCtl/NetState.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: 0626c2db7c48f1646821d77eb3d8f3e6 |
| | | timeCreated: 1519302437 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
New file |
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | using System; |
| | | |
| | | public class NetUpdateBehaviour : MonoBehaviour |
| | | { |
| | | Action onUpdate; |
| | | public void RegisterUpdateCallBack(Action _onUpdate) |
| | | { |
| | | onUpdate += _onUpdate; |
| | | } |
| | | |
| | | void Update() |
| | | { |
| | | #if UNITY_EDITOR |
| | | |
| | | if (Input.GetKey(KeyCode.LeftShift) && Input.GetKeyDown(KeyCode.Escape)) |
| | | { |
| | | GameNetSystem.Instance.LoginOut(); |
| | | } |
| | | #endif |
| | | |
| | | if (onUpdate!=null) |
| | | { |
| | | onUpdate(); |
| | | } |
| | | } |
| | | |
| | | private void OnApplicationQuit() |
| | | { |
| | | GameNetSystem.Instance.Disconnect(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: d9f19d1b8cac52440a9b08b5b3a131d8 |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
New file |
| | |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | public class NeverConnectState : NetState |
| | | { |
| | | |
| | | public override void OnEnter() |
| | | { |
| | | base.OnEnter(); |
| | | // NetLinkWin.Hide(); |
| | | } |
| | | |
| | | protected override void Update() |
| | | { |
| | | if (GameNetSystem.Instance.netState != GameNetSystem.NetState.NerverConnect) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | } |
| | | |
| | | public override void OnExit() |
| | | { |
| | | base.OnExit(); |
| | | } |
| | | |
| | | } |
copy from Utility/StringUtility.cs.meta
copy to Main/NetworkPackage/DataToCtl/NeverConnectState.cs.meta
File was copied from Utility/StringUtility.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: c0960ed66238bdd49b70860dfee23488 |
| | | timeCreated: 1475005527 |
| | | licenseType: Free |
| | | guid: 6cc286e08ca8714449e69d7573918a06 |
| | | timeCreated: 1519301439 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
New file |
| | |
| | | using UnityEngine; |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | //using ILCrossBinding; |
| | | |
| | | public class PackageRegedit |
| | | { |
| | | #region 主工程原生的封包 |
| | | static object lockojb1 = new object(); |
| | | static Dictionary<ushort, Type> m_PackageTable = new Dictionary<ushort, Type>(); |
| | | static Dictionary<ushort, Type> packageTable |
| | | { |
| | | get |
| | | { |
| | | lock (lockojb1) { return m_PackageTable; } |
| | | } |
| | | } |
| | | static object lockojb2 = new object(); |
| | | static Dictionary<ushort, DtcBasic> m_PackToBusinessTable = new Dictionary<ushort, DtcBasic>(); |
| | | static Dictionary<ushort, DtcBasic> packToBusinessTable |
| | | { |
| | | get |
| | | { |
| | | lock (lockojb2) { return m_PackToBusinessTable; } |
| | | } |
| | | } |
| | | #endregion |
| | | |
| | | public static void Init() |
| | | { |
| | | // 登记相应的数据体及对应的数据转逻辑类 |
| | | // Register(typeof(HA328_tagMCHistoryReChargeAwardRecord), typeof(DTCA328_tagMCHistoryReChargeAwardRecord)); |
| | | |
| | | } |
| | | |
| | | |
| | | //主工程注册封包 |
| | | public static void Register(Type _pack, Type _business) |
| | | { |
| | | var packInstance = _pack.Assembly.CreateInstance(_pack.Name) as GameNetPackBasic; |
| | | var businessInstance = _business.Assembly.CreateInstance(_business.Name) as DtcBasic; |
| | | if (packToBusinessTable.ContainsKey(packInstance.cmd)) |
| | | { |
| | | Debug.LogErrorFormat("重复封包登记: {0}!", _pack.Name); |
| | | } |
| | | else |
| | | { |
| | | packToBusinessTable[packInstance.cmd] = businessInstance; |
| | | packageTable[packInstance.cmd] = _pack; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | public static bool Contain(ushort _cmd) |
| | | { |
| | | return packToBusinessTable.ContainsKey(_cmd); |
| | | } |
| | | public static void Distribute(GameNetPackBasic _package) |
| | | { |
| | | try |
| | | { |
| | | //执行主工程的封包 |
| | | if (packToBusinessTable.ContainsKey(_package.cmd)) |
| | | packToBusinessTable[_package.cmd].Done(_package); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogError(ex.Message + "\r\n" + ex.StackTrace); |
| | | Debug.LogErrorFormat("封包是否为Null:{0};", _package == null); |
| | | if (_package != null) |
| | | { |
| | | Debug.LogErrorFormat("封包编号是:{0};", _package.cmd); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 转换一个协议包 |
| | | /// </summary> |
| | | /// <param name="vBytes"></param> |
| | | /// <returns></returns> |
| | | public static GameNetPackBasic TransPack(ServerType socketType, ushort cmd, byte[] vBytes) |
| | | { |
| | | #if UNITY_EDITOR |
| | | int length = vBytes.Length; |
| | | string vStr = ""; |
| | | for (int i = 0; i < length; i++) |
| | | { |
| | | vStr += vBytes[i].ToString("x2").ToUpper() + ","; |
| | | } |
| | | #endif |
| | | // 主工程有登记 |
| | | if (packageTable.ContainsKey(cmd)) |
| | | { |
| | | var packageType = packageTable[cmd]; |
| | | // 实例化并强转为协议包基类 |
| | | var packageInstance = packageType.Assembly.CreateInstance(packageType.Name) as GameNetPackBasic; |
| | | packageInstance.ReadFromBytes(vBytes);// 解析内容 |
| | | if (packageInstance.cmd == (ushort)0x03F0 || packageInstance.cmd == (ushort)0x1801) |
| | | { |
| | | byte[] vPyBody = new byte[vBytes.Length - 4]; |
| | | Array.Copy(vBytes, 4, vPyBody, 0, vPyBody.Length); |
| | | packageInstance = TransForPyPack(vPyBody); |
| | | } |
| | | |
| | | packageInstance.socketType = socketType; |
| | | #if UNITY_EDITOR |
| | | NetPkgCtl.RecordPackage(socketType, vStr, NetPackagetType.Server, packageInstance.ToString(), FieldPrint.PrintFields(packageInstance), FieldPrint.PrintFieldsExpand(packageInstance, true)); |
| | | #endif |
| | | return packageInstance; |
| | | } |
| | | else //未注册 |
| | | { |
| | | #if UNITY_EDITOR |
| | | NetPkgCtl.RecordPackage(socketType, vStr, NetPackagetType.Server, string.Empty, string.Empty, null); |
| | | #endif |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 解析PY的模拟包 |
| | | /// </summary> |
| | | /// <param name="vBytes"></param> |
| | | /// <returns></returns> |
| | | private static GameNetPackBasic TransForPyPack(byte[] vBytes) |
| | | { |
| | | GameNetPackBasic vNetPackInst = null; |
| | | ushort vPackCmd = (ushort)((ushort)(vBytes[0] << 8) + vBytes[1]); |
| | | // 主工程封包 |
| | | if (packageTable.ContainsKey(vPackCmd)) |
| | | { |
| | | Type vNetPackType = packageTable[vPackCmd]; |
| | | vNetPackInst = vNetPackType.Assembly.CreateInstance(vNetPackType.Name) as GameNetPackBasic; |
| | | vNetPackInst.ReadFromBytes(vBytes);// 解析内容 |
| | | } |
| | | else |
| | | { |
| | | Debug.Log("收到未定义的解包协议:" + vBytes[0].ToString("x2").ToUpper() + "," + vBytes[1].ToString("x2").ToUpper()); |
| | | } |
| | | return vNetPackInst; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: b019a6de742f30a45899664d4938287f |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
New file |
| | |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | |
| | | public class RoleLoginState : NetState |
| | | { |
| | | const int OVERTIME_THRESHOLD_1 = 20; |
| | | const int OVERTIME_THRESHOLD_2 = 10; |
| | | |
| | | float timer1 = 0f; |
| | | float timer2 = 0f; |
| | | |
| | | public override void OnEnter() |
| | | { |
| | | base.OnEnter(); |
| | | timer1 = 0f; |
| | | timer2 = 0f; |
| | | } |
| | | |
| | | protected override void Update() |
| | | { |
| | | if (GameNetSystem.Instance.netState != GameNetSystem.NetState.RoleLogin) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | timer1 += Time.deltaTime; |
| | | if (timer1 > OVERTIME_THRESHOLD_1) |
| | | { |
| | | GameNetSystem.Instance.Disconnect(); |
| | | // WindowCenter.Instance.Open<DisconnectHintWin>(); |
| | | } |
| | | |
| | | |
| | | timer2 += Time.deltaTime; |
| | | if (timer2 > OVERTIME_THRESHOLD_2) |
| | | { |
| | | GameNetSystem.Instance.Disconnect(); |
| | | // WindowCenter.Instance.Open<DisconnectHintWin>(); |
| | | } |
| | | } |
| | | |
| | | public override void OnExit() |
| | | { |
| | | base.OnExit(); |
| | | } |
| | | |
| | | } |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/NetworkPackage/DataToCtl/RoleLoginState.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: c0696575305fead4f96cf7726264e959 |
| | | timeCreated: 1519302335 |
| | | licenseType: Pro |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
New file |
| | |
| | | using System.Collections.Generic; |
| | | |
| | | public class DebugPkgCache |
| | | { |
| | | private string dataTime; |
| | | private int code; |
| | | |
| | | private static List<DebugPkgCache> m_List = new List<DebugPkgCache>(); |
| | | |
| | | public static void Push(GameNetPackBasic package) |
| | | { |
| | | if (m_List.Count != 0) |
| | | { |
| | | if (m_List[m_List.Count - 1].code == 258) |
| | | { |
| | | return; |
| | | } |
| | | } |
| | | |
| | | DebugPkgCache _p = new DebugPkgCache(); |
| | | _p.dataTime = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); |
| | | _p.code = package.cmd; |
| | | |
| | | m_List.Add(_p); |
| | | } |
| | | |
| | | public static void UpLoad() |
| | | { |
| | | var _contents = new System.Text.StringBuilder(); |
| | | foreach (var _content in m_List) |
| | | { |
| | | _contents.Append("["); |
| | | _contents.Append(_content.dataTime); |
| | | _contents.Append("]"); |
| | | _contents.Append(_content.code); |
| | | _contents.Append("\r\n"); |
| | | } |
| | | |
| | | #if UNITY_EDITOR |
| | | UnityEngine.Debug.Log("登陆异常: " + _contents.ToString()); |
| | | #endif |
| | | _contents = null; |
| | | |
| | | m_List.Clear(); |
| | | } |
| | | } |
copy from Utility/StringUtility.cs.meta
copy to Main/NetworkPackage/DebugPkgCache.cs.meta
File was copied from Utility/StringUtility.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: c0960ed66238bdd49b70860dfee23488 |
| | | timeCreated: 1475005527 |
| | | guid: 90b1b61b46516f047a22f3e5920983cd |
| | | timeCreated: 1538230240 |
| | | licenseType: Free |
| | | MonoImporter: |
| | | serializedVersion: 2 |
New file |
| | |
| | | using UnityEngine; |
| | | using System; |
| | | using System.Collections; |
| | | using System.Text; |
| | | |
| | | /** 字节流的加解密 */ |
| | | public class GameNetEncode |
| | | { |
| | | int[] gSendKeyDict = new int[1024] //发送加密用密钥 |
| | | { |
| | | 0x3bc46229, 0x71463c13, 0x4df97c63, 0x20a6b7b6, 0x5cb0c110, 0x780d5397, 0x161f22f9, 0x71f1eda0, |
| | | 0x4c4797a4, 0x7b3d7177, 0x2679595a, 0x54c92286, 0x2af45923, 0x2e5cd5f4, 0x5bc860c7, 0x14929ca9, |
| | | 0x1fef64cf, 0x30a25d4c, 0x5daf8680, 0x4553de47, 0x787d45e5, 0x5631bfc0, 0x6de263c5, 0x3493e5a1, |
| | | 0x6559f3a9, 0x3833d191, 0x799e1dd6, 0x55b96cf7, 0x71901158, 0x740ac2fc, 0x66aea5f4, 0x58252a89, |
| | | 0x59fc2e33, 0x7de26045, 0x513ff95d, 0x71481097, 0x38bc057b, 0x66dc51a9, 0x6bbb6152, 0x60f58d62, |
| | | 0x63c9be6e, 0x13185b6a, 0x4df0b314, 0x7231cb28, 0x4a032c4d, 0x67d89dc5, 0x3ccb8fe1, 0x16bbf02b, |
| | | 0x35dd0e58, 0x2601d4fe, 0x7fd4a4fa, 0x57945ea8, 0x59024fcf, 0x31379952, 0x35beeba0, 0x40bef4e3, |
| | | 0x601f47f3, 0x6fd49f02, 0x4540e911, 0x4a814d19, 0x4a18fa02, 0x5bfef64f, 0x4379ee8e, 0x7e5cfd8b, |
| | | 0x49f0553d, 0x7a184b77, 0x45235957, 0x7205d879, 0x369174e5, 0x44ca26bb, 0x4bcdd2ad, 0x6e942c24, |
| | | 0x77cee037, 0x7aee2c5b, 0x2c6a8fce, 0x263302ca, 0x5bc8ca77, 0x57925c98, 0x486091fb, 0x368a62ad, |
| | | 0x5c0052e2, 0x785953b0, 0x7e6de674, 0x72258e0a, 0x1556c4ba, 0x727689e4, 0x1494e67a, 0x67154325, |
| | | 0x7238d73c, 0x52869374, 0x2855774b, 0x450dfc3b, 0x4235edac, 0x7f8360a0, 0x3e724a28, 0x61422f8d, |
| | | 0x56435747, 0x45147da9, 0x57821c51, 0x52388f5c, 0x54eb8f4e, 0x357b52cd, 0x5a8cf707, 0x79de49e5, |
| | | 0x45a97d02, 0x1f5b644e, 0x22f56f88, 0x3015496c, 0x1eafb3a1, 0x2f9e926a, 0x1aede716, 0x6bfe742e, |
| | | 0x5c5bb26c, 0x43b55962, 0x37b9caef, 0x163fec6d, 0x359524a4, 0x6c731176, 0x18fad454, 0x3a875067, |
| | | 0x2c592187, 0x7dc62ee6, 0x184a4885, 0x3a87fa5d, 0x15b16c57, 0x238c81f3, 0x225e38c3, 0x70b5408f, |
| | | 0x7057b451, 0x2fc376db, 0x4efac24b, 0x6cf8b53d, 0x1d44d4b9, 0x425455df, 0x48ef4e61, 0x71a466a8, |
| | | 0x496c14cc, 0x46bc8340, 0x635fd242, 0x62e11f0e, 0x63e267cb, 0x3fd1bf3c, 0x559a0f2f, 0x16d8a4b1, |
| | | 0x17b1acf7, 0x65e26614, 0x72b6d268, 0x40dbf9cf, 0x5c97ef8d, 0x3771b008, 0x3e47352e, 0x3dc59ca9, |
| | | 0x4df2a6d1, 0x78cff158, 0x4b4ddcbf, 0x13d7c780, 0x2315f600, 0x6aceda44, 0x4ec43a5c, 0x1456b092, |
| | | 0x304fec5c, 0x1cd1b70d, 0x6aebcb45, 0x691eca1f, 0x63d7c522, 0x5a79aff1, 0x24ab58bb, 0x5477026a, |
| | | 0x6de92795, 0x412e0932, 0x103837fc, 0x155f03b1, 0x6f4b66f5, 0x15c0630e, 0x6e4b8a49, 0x2e997433, |
| | | 0x6584c280, 0x6e6cf9c6, 0x3f237ce3, 0x5ab23630, 0x27f9a578, 0x4176e59a, 0x6c908907, 0x2340a7eb, |
| | | 0x2537e71b, 0x74a05aca, 0x584eb3f9, 0x1da5e3a2, 0x1bae0aaa, 0x65bee996, 0x67eacef6, 0x4b86ff93, |
| | | 0x250e7f66, 0x60abbe3f, 0x1373b740, 0x19434e02, 0x379ee08d, 0x52cfe103, 0x58379615, 0x30a69d2c, |
| | | 0x7cb3355f, 0x788c7623, 0x4ccd20b6, 0x52177752, 0x2795311f, 0x3cbefde0, 0x6fa8d863, 0x328162b5, |
| | | 0x7417730a, 0x5ea19478, 0x757e4a5c, 0x683b2192, 0x1014c662, 0x6e47322c, 0x78ad4fe1, 0x1d28f22d, |
| | | 0x2f1b6265, 0x6bf3eb3c, 0x16fb4e33, 0x285acec3, 0x53842a54, 0x22912fe9, 0x36d87690, 0x2d66ad96, |
| | | 0x1435ed70, 0x717e0c71, 0x79710639, 0x5bbec0e3, 0x6254a6f6, 0x55fb6915, 0x5aca866f, 0x2443b6ee, |
| | | 0x1e1cbe2a, 0x40744a16, 0x4d2d0c70, 0x5752f9f4, 0x162a464a, 0x7de20fb1, 0x1918797e, 0x5990f036, |
| | | 0x686c3e94, 0x398cb62a, 0x3705bad7, 0x29af3bf5, 0x1803d24c, 0x176715bf, 0x243409bc, 0x6d6efb6f, |
| | | 0x574f98af, 0x234722af, 0x7fc22b6c, 0x681f08e5, 0x7162d4fe, 0x3d3a2d3b, 0x1953b12b, 0x68d63a97, |
| | | 0x4a28b679, 0x373521a3, 0x36823834, 0x7aa9a2c5, 0x58739860, 0x7460c827, 0x705aa9c8, 0x5d1ecfb0, |
| | | 0x293841f4, 0x76420507, 0x66267b2a, 0x371a0b96, 0x17352673, 0x4ffe1884, 0x2ec0ed97, 0x42889cb8, |
| | | 0x7e45a51e, 0x73fadedc, 0x6db84e50, 0x6b070556, 0x3da14936, 0x3c1b1050, 0x6d7b3695, 0x15c343b1, |
| | | 0x684709f9, 0x78d68120, 0x2bd1cba7, 0x24db1207, 0x4ed48aa8, 0x1f6e618d, 0x21e2fec5, 0x3476269a, |
| | | 0x4a095a83, 0x7b7d7dd5, 0x1d05cd2e, 0x5bdc73a7, 0x693634ca, 0x34247e39, 0x599e8023, 0x38c86772, |
| | | 0x73d840bd, 0x711226f9, 0x4d47ece4, 0x67352c38, 0x39a0519d, 0x27a79856, 0x4988b4b1, 0x43e8e83a, |
| | | 0x282626a9, 0x34788e8e, 0x4c5484ca, 0x63fafdb8, 0x7987ab1f, 0x7167a1e2, 0x7f99566f, 0x57964af3, |
| | | 0x7b343642, 0x549e8692, 0x2518aee1, 0x5a376a29, 0x6823cb52, 0x30a24cdf, 0x17ccdf5f, 0x5ea6f19b, |
| | | 0x1dba598e, 0x49c3a107, 0x281a4528, 0x10efb38a, 0x6e96fc34, 0x512b0b4b, 0x340c897d, 0x7490fe33, |
| | | 0x428f3a88, 0x31c12fec, 0x68dfe19e, 0x712cdbda, 0x4f1647c7, 0x27330f28, 0x27164ecb, 0x1bf252bd, |
| | | 0x3f504332, 0x63524540, 0x5e58de44, 0x5803a51a, 0x4f117809, 0x32114a74, 0x5264e94a, 0x54189135, |
| | | 0x18099d8d, 0x285bb305, 0x6645551b, 0x379c914b, 0x1c5b16fc, 0x160a6f31, 0x5717d2f8, 0x3d891b9d, |
| | | 0x55de3397, 0x6f340b39, 0x5b9e2021, 0x473be26c, 0x3d506e9f, 0x1d18ef5e, 0x79db45d6, 0x1d8913f6, |
| | | 0x78afaf51, 0x62eb9fdd, 0x7ffcd957, 0x42499a7c, 0x5c0188f1, 0x1eb4fcfa, 0x19d03be6, 0x40a55c3e, |
| | | 0x63c67abc, 0x2a9482f2, 0x5803dabe, 0x46597b7d, 0x1c592ff4, 0x2e9c8a06, 0x3a746f24, 0x1c3a9677, |
| | | 0x6579bfd7, 0x2f8a8677, 0x4ac63e55, 0x3033076d, 0x4d44eda6, 0x729b4882, 0x108a5993, 0x4efd249f, |
| | | 0x49d768a1, 0x6abb3c6b, 0x542fde1b, 0x17d9804e, 0x14dd0c09, 0x1f52aa70, 0x42013531, 0x108128b8, |
| | | 0x184c1f1c, 0x28edf6d0, 0x2a6d5412, 0x2b93e81e, 0x278c951b, 0x6c01e1cb, 0x28dcfbff, 0x1fc284c1, |
| | | 0x4c4b4d46, 0x760bc7a4, 0x6653fa38, 0x59f500de, 0x3a3952de, 0x1d4de099, 0x791e67fd, 0x40acdab9, |
| | | 0x38f71d21, 0x6f6780e8, 0x4ec9ea8f, 0x3ae34c8f, 0x4f6bcf50, 0x470958d5, 0x59aaf32c, 0x78a38ca1, |
| | | 0x47c878ab, 0x2d05b49d, 0x272dff16, 0x17a10d30, 0x2f775473, 0x54fcbc81, 0x5034d78b, 0x5a09bc7a, |
| | | 0x323709e6, 0x31e4b4c2, 0x20bfd1cc, 0x71d444c0, 0x1ba1ec45, 0x3aae3d9e, 0x10230f1a, 0x4eca4c42, |
| | | 0x36613ad0, 0x73449356, 0x4f07bcb2, 0x798eb540, 0x1c4c60c8, 0x7a29ce2a, 0x5c7953d8, 0x11dfddfb, |
| | | 0x76b4356a, 0x46ef225b, 0x4f3ed9c9, 0x4255e0b1, 0x1a1a3bfa, 0x71c92026, 0x3cc01fc6, 0x77dcd3a3, |
| | | 0x4493e3b5, 0x187ff3cf, 0x62b7030f, 0x272b0912, 0x5219c7dc, 0x30fba593, 0x74ecace4, 0x36734f3c, |
| | | 0x6602efb0, 0x15ac59b4, 0x7c42d285, 0x6d933062, 0x64ec0e6f, 0x240e9070, 0x2048f534, 0x5afd32c4, |
| | | 0x764ac35a, 0x318b6608, 0x509da22c, 0x479f18a3, 0x10ecd9b2, 0x56f4d2bc, 0x6f5bb2b1, 0x4004203d, |
| | | 0x21a388b5, 0x2eddeacd, 0x69d38c03, 0x24f343d3, 0x475ab3a4, 0x2f0f1e79, 0x38d05f60, 0x51c979a5, |
| | | 0x4bdc29bf, 0x21567a01, 0x4da96a09, 0x52cff3f4, 0x3c7ee647, 0x5bf3e5a5, 0x6d5f353e, 0x41ce60fe, |
| | | 0x3202507a, 0x15e165a6, 0x4704d640, 0x4b192b04, 0x12d57b9a, 0x6f375a41, 0x5eb52e4d, 0x195bb847, |
| | | 0x270a66e5, 0x31ecbfba, 0x42542aa6, 0x725eab04, 0x61353d9b, 0x6b336e4e, 0x495c048c, 0x3b0a217f, |
| | | 0x4b7796ff, 0x69b05a3e, 0x1cf6813d, 0x24e3f5f5, 0x53f7b64e, 0x28cfd3cb, 0x11a231fb, 0x5349fea7, |
| | | 0x1003caca, 0x3d75c733, 0x17a3b404, 0x62a84dd5, 0x19212fb1, 0x1449fcb8, 0x5382f099, 0x47eb71c0, |
| | | 0x4347ac44, 0x3de05898, 0x1bd45cfa, 0x2a6eb4a6, 0x2788b3c3, 0x30fd1b14, 0x158e3a68, 0x16a65cc9, |
| | | 0x3a62a56e, 0x1735206c, 0x7429d620, 0x13c5ec67, 0x71000c85, 0x742a20e0, 0x4ed0c966, 0x62a261c1, |
| | | 0x24a2e049, 0x23a2f0b1, 0x77d63977, 0x78107717, 0x5f7bc3f8, 0x46bfc01d, 0x1fbc1795, 0x30fee2aa, |
| | | 0x3a2d46d3, 0x648a5b65, 0x690460fd, 0x4a8c96b8, 0x7d3b241a, 0x3e226ac9, 0x2e0e5ef3, 0x245b0182, |
| | | 0x45a5830e, 0x62c5b289, 0x663fe6b4, 0x1f5c4d48, 0x17f036ed, 0x5bf452e6, 0x73ba9981, 0x475da04a, |
| | | 0x68d5fef8, 0x65f1081e, 0x5edd249a, 0x318d5cc9, 0x7ee7c66f, 0x14dd6a73, 0x60d0813f, 0x463d6103, |
| | | 0x7c57e492, 0x12b22e23, 0x2a6134b1, 0x68214739, 0x4c315ca2, 0x1e53636f, 0x7064902e, 0x5748a5ab, |
| | | 0x3a3b1ddd, 0x2000b697, 0x32e9f0f8, 0x2a154e9a, 0x38c74385, 0x5361afdb, 0x6078004c, 0x326d9044, |
| | | 0x33ae54d8, 0x236df37c, 0x1295f36e, 0x316a74ea, 0x6bb68517, 0x407181b8, 0x2ce0cb9b, 0x77c202cc, |
| | | 0x11a6f383, 0x546cf6d0, 0x63ec9614, 0x3d2d7c2b, 0x5446eb59, 0x2611cb05, 0x4d31ac1a, 0x650b9f45, |
| | | 0x408923dd, 0x469a9295, 0x5545f2eb, 0x127ee65c, 0x2f23004c, 0x42bf3dc1, 0x55a21bc8, 0x2a47c7ae, |
| | | 0x76cfcfe7, 0x4b0558c9, 0x2f32e3f2, 0x4c9af57c, 0x46800def, 0x23ac4bee, 0x5af654a7, 0x6d339e06, |
| | | 0x56b4a1a2, 0x38759b6e, 0x7de50327, 0x5be1ab8c, 0x1d461e41, 0x2c89278a, 0x496750b5, 0x4bd4044e, |
| | | 0x6ad8030c, 0x6ab56c82, 0x7d96aa8e, 0x43deca8d, 0x2537fb44, 0x164bc297, 0x3e8ac9f4, 0x6dfd9c87, |
| | | 0x6de91e26, 0x28d89e07, 0x29f2f425, 0x6851d47d, 0x501b2ef6, 0x14f7cf13, 0x263b3a62, 0x35dcc8b0, |
| | | 0x1d4ddcf2, 0x7284c1fb, 0x407db9ec, 0x49360b5e, 0x4be00359, 0x4466beff, 0x5a7fdc01, 0x6f7daac8, |
| | | 0x66cae96c, 0x44392a60, 0x35fb95e2, 0x1dca712f, 0x19c9826b, 0x1c0fc45c, 0x3674a8cf, 0x1f5424d1, |
| | | 0x212bad97, 0x5296e934, 0x3ed9e209, 0x7e99c7ee, 0x2095762e, 0x19cfd129, 0x4c325ace, 0x1fc3d8c9, |
| | | 0x1fea5371, 0x3ca8d079, 0x6a96b85f, 0x1e82919f, 0x49a468a0, 0x63b19765, 0x5db66bfc, 0x6da828b1, |
| | | 0x31d7c4fc, 0x252b722d, 0x5228f2e5, 0x52bf1040, 0x5921a3c2, 0x50b58911, 0x18cb165b, 0x53dc368a, |
| | | 0x6ac3ac36, 0x22d52052, 0x39682b9c, 0x39ed45d0, 0x312b3195, 0x2899d82e, 0x65ef53e9, 0x25c2e453, |
| | | 0x28247321, 0x279dece6, 0x2374bc83, 0x7216f450, 0x6ff9dc17, 0x4aa276ba, 0x7a3edea7, 0x28ced40b, |
| | | 0x10bf43bb, 0x5f07a9ea, 0x5a1fbf99, 0x7db99dc1, 0x59092d4a, 0x5b6116b7, 0x4c5a3096, 0x2d0a67b4, |
| | | 0x7f500805, 0x4365e95f, 0x58530edf, 0x57ce8421, 0x793f6f2c, 0x397d2a23, 0x1c4e83b5, 0x449fc14c, |
| | | 0x48316a00, 0x5a25fd43, 0x77794456, 0x16d2a973, 0x6615abbf, 0x197be300, 0x1e7dd204, 0x6a60c2d4, |
| | | 0x3a04d3aa, 0x7716f798, 0x3fe5b9fd, 0x3ececfb3, 0x57bfad01, 0x3888334c, 0x4986d582, 0x674f0e4d, |
| | | 0x695a6f05, 0x36b1aa5d, 0x5c3c89d3, 0x225f78e3, 0x7e53fcf4, 0x263acd09, 0x472d0830, 0x672405b5, |
| | | 0x7759260f, 0x5f60a791, 0x4fda8dd9, 0x72bce703, 0x41f3e597, 0x45622235, 0x6840a40e, 0x7bd8cb0d, |
| | | 0x3366a2ca, 0x59c84135, 0x403d6010, 0x5ec31c14, 0x7df370e9, 0x43ca64d2, 0x1b86a31e, 0x602e4056, |
| | | 0x27cf4f35, 0x100e894a, 0x416b5a76, 0x30f9da15, 0x670168eb, 0x390586de, 0x77a0bf5b, 0x5935078f, |
| | | 0x516e554f, 0x142351cf, 0x355b970d, 0x3c9ca305, 0x7c4f579e, 0x7c333a5a, 0x57f572ca, 0x26d582b8, |
| | | 0x12559f1a, 0x7d082cc3, 0x3e5defd4, 0x79a2b8e5, 0x23b98701, 0x30c8f147, 0x7c97f768, 0x6357d3d0, |
| | | 0x3f75d694, 0x3b186c28, 0x7482feca, 0x5fc71db6, 0x70ef0113, 0x3a59dda4, 0x5d304737, 0x31ebdcd9, |
| | | 0x494665be, 0x635121fc, 0x4e041df0, 0x50909377, 0x47998fd6, 0x175ef171, 0x5ee31c35, 0x6c313fd1, |
| | | 0x1f6d7699, 0x11992041, 0x5aab6747, 0x30599c27, 0x4885bd48, 0x72fedeac, 0x3d39f064, 0x7ebf5eb9, |
| | | 0x3f67f323, 0x3208f8f5, 0x323bb4ce, 0x6e5879c7, 0x19cad36b, 0x7dd61759, 0x360afdc3, 0x54ad5b92, |
| | | 0x5e31855e, 0x5132fe19, 0x75d8a084, 0x3ba72e58, 0x69f2dc3d, 0x1dbecd76, 0x28613e51, 0x521a185a, |
| | | 0x2cec9749, 0x436b41ae, 0x246e846b, 0x614b7bd8, 0x7e22a1bf, 0x6498f302, 0x26646c10, 0x3db43713, |
| | | 0x788a52e2, 0x130f95b3, 0x321a7a81, 0x353ee449, 0x7b41adf2, 0x1e1239ff, 0x4a4100fe, 0x294219bc, |
| | | 0x4472a22d, 0x65cf8c27, 0x42925cc7, 0x7e76a9a9, 0x1a224ad5, 0x446e146b, 0x3e10371d, 0x4929e254, |
| | | 0x602c2f28, 0x48f4770b, 0x568cc53e, 0x77ebcdfa, 0x56a98267, 0x2c4db448, 0x36c0086b, 0x2af972dd, |
| | | 0x580463d2, 0x44a96860, 0x6c290de4, 0x52a3133b, 0x39f71eaa, 0x47780b94, 0x51fb2eea, 0x5aee6d55, |
| | | 0x20b76a2d, 0x36433225, 0x425750bb, 0x76b4fb6b, 0x1f8da99c, 0x1ea1cc51, 0x17112499, 0x587e33bd, |
| | | 0x5e182c37, 0x41886659, 0x1f4067c2, 0x2355c88c, 0x157a6d3f, 0x4235687d, 0x4ade2377, 0x49dde816, |
| | | 0x64b853f2, 0x78f956fd, 0x69adecf8, 0x3ddd7c9c, 0x577d7391, 0x521b121a, 0x16b32586, 0x4e8a6c5e, |
| | | 0x16904b5d, 0x1d181612, 0x15723a5f, 0x3fcfd99d, 0x65318693, 0x1c80bb27, 0x723de4c3, 0x10d06297, |
| | | 0x5aa73c77, 0x62b07596, 0x72d069f5, 0x33e4618d, 0x33343046, 0x53a215a3, 0x4070db32, 0x56542cbf, |
| | | 0x6fbb1141, 0x4020078b, 0x60e455bb, 0x520e566e, 0x674dbaa8, 0x3a90938f, 0x6f6b42d0, 0x6f99ecd8, |
| | | 0x69e873bc, 0x219e1df0, 0x630a97b2, 0x6a84ba3e, 0x4f992fbb, 0x28fb66ec, 0x5b61159f, 0x468d84e0, |
| | | 0x1b52cde7, 0x6483cac4, 0x494889d8, 0x6fca4efe, 0x24ac597e, 0x25f781b9, 0x74830d9d, 0x7c0a96d8, |
| | | 0x17cc49c1, 0x4993e008, 0x7bb4462e, 0x5fb596af, 0x26bfc1f0, 0x49c795f5, 0x37e6a4cc, 0x246484c2, |
| | | 0x737dd14b, 0x6e42efbd, 0x58dca6b5, 0x6b78d34f, 0x15d6b313, 0x46a415a1, 0x3b6e152b, 0x72ee7099, |
| | | 0x4c8f0e86, 0x7cff4be1, 0x3731456c, 0x7eaa06e0, 0x54e736e5, 0x488332be, 0x6cb058b9, 0x54833c62, |
| | | 0x4fce6b70, 0x64790676, 0x796a7c52, 0x754af360, 0x58021767, 0x1be0df4b, 0x32e12978, 0x290d8a1b, |
| | | 0x5859120b, 0x45e9f17b, 0x55f16569, 0x20d11ad1, 0x7d7ade9a, 0x1b86cd47, 0x73b90166, 0x7c0fbbc3, |
| | | 0x7a42ec55, 0x6a5d9eef, 0x4147daaf, 0x6c2dbf31, 0x520fd67c, 0x65546eb3, 0x7b5d1a84, 0x1c2bf35c, |
| | | 0x383ea450, 0x5ef960d3, 0x1b707626, 0x5ed5e282, 0x4012090f, 0x1606f590, 0x47476ed3, 0x21ac12e5, |
| | | 0x4445a3fa, 0x48444928, 0x205691cd, 0x7eca46c2, 0x198d4052, 0x7c0153dc, 0x542eb852, 0x5409bc5d, |
| | | 0x3b401555, 0x7c6f29ec, 0x3b3647a3, 0x519f6df3, 0x2d700644, 0x71143b98, 0x3eee7100, 0x2e7651c6, |
| | | 0x3bace25f, 0x449c9521, 0x5d0471a9, 0x7c859a13, 0x17b3a4e7, 0x7b461ec5, 0x286ed2df, 0x2362f51e, |
| | | 0x3749b51a, 0x2528dcc6, 0x15d6a9e0, 0x5350cd24, 0x1c842639, 0x649b2f61, 0x7c8cd7ed, 0x7f088866, |
| | | 0x7fbaf784, 0x3cf212da, 0x114b4a47, 0x7680c924, 0x3e68543c, 0x59dd5f6e, 0x1c023a2c, 0x18efad9f, |
| | | 0x7e33d39e, 0x6ba0095e, 0x35f16cdd, 0x70491015, 0x1f69b8ee, 0x506460eb, 0x594d739a, 0x1478c6c8 |
| | | }; |
| | | |
| | | byte[] gSendKeyBytes;//加工后的加密钥 |
| | | int m_KeyEncodeIndex = 250; |
| | | public int KeyEncodeIndex { |
| | | get { return m_KeyEncodeIndex; } |
| | | set { m_KeyEncodeIndex = value; } |
| | | } |
| | | |
| | | /** 解密用字串 */ |
| | | byte[] gKeyBytes = new byte[] { 184, 187, 199, 191, 32, 195, 241, 214, 247, 32, 206, 196, 195, 247, 32, 186, 205, 208, 179, 32, 215, 212, 211, 201, 32, 198, 189, 181, 200, 32, 185, 171, 213, 253, 32, 183, 168, 214, 206, 32, 176, 174, 185, 250, 32, 190, 180, 210, 181, 32, 179, 207, 208, 197, 32, 211, 209, 201, 198 }; |
| | | |
| | | /// <summary> |
| | | /// 加密 |
| | | /// </summary> |
| | | /// <param name="vBuffer"></param> |
| | | /// <returns></returns> |
| | | public byte[] BaseXorAdd(byte[] vBuffer) |
| | | { |
| | | ConfigEncodeKey(); |
| | | return BaseXorAdd(vBuffer, gSendKeyBytes); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 加密 |
| | | /// </summary> |
| | | /// <param name="vBuffer"></param> |
| | | /// <param name="vPassword"></param> |
| | | /// <returns></returns> |
| | | byte[] BaseXorAdd(byte[] vBuffer, byte[] vPassword) |
| | | { |
| | | int i; |
| | | int l = vBuffer.Length; |
| | | byte vSubBuffer; |
| | | byte vSingleRst; |
| | | byte ucByte = 0; |
| | | int vKeyLeng = vPassword.Length; |
| | | int vKeyIndex; |
| | | for (i = 0; i < l; i++) |
| | | { |
| | | vKeyIndex = i % vKeyLeng; |
| | | vSubBuffer = vBuffer[i]; |
| | | vSingleRst = (byte)(vSubBuffer ^ vPassword[vKeyIndex]); |
| | | vSingleRst ^= ucByte; |
| | | ucByte += vSubBuffer; |
| | | vSingleRst ^= (byte)i; |
| | | vSingleRst ^= 0x78; |
| | | vSingleRst ^= 0x05; |
| | | vSingleRst ^= 0x27; |
| | | |
| | | vBuffer[i] = vSingleRst; |
| | | } |
| | | return vBuffer; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 解密 |
| | | /// </summary> |
| | | /// <param name="vBuffer"></param> |
| | | /// <returns></returns> |
| | | public byte[] BaseXorSub(byte[] vBuffer) |
| | | { |
| | | return BaseXorSub(vBuffer, gKeyBytes); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 解密 |
| | | /// </summary> |
| | | /// <param name="vBuffer"></param> |
| | | /// <param name="vPassword"></param> |
| | | /// <returns></returns> |
| | | byte[] BaseXorSub(byte[] vBuffer, byte[] vPassword) |
| | | { |
| | | int i; |
| | | byte ucByte = 0; |
| | | byte ucTemp = 0; |
| | | int l = vBuffer.Length; |
| | | byte vSubBuffer; |
| | | byte vSingleRst; |
| | | int vKeyLeng = vPassword.Length; |
| | | int vKeyIndex; |
| | | for (i = 0; i < l; i++) |
| | | { |
| | | vKeyIndex = i % vKeyLeng; |
| | | vSubBuffer = vBuffer[i]; |
| | | vSingleRst = (byte)(vSubBuffer ^ 0x78); |
| | | vSingleRst ^= 0x05; |
| | | vSingleRst ^= 0x27; |
| | | vSingleRst ^= (byte)i; |
| | | ucByte += ucTemp; |
| | | vSingleRst ^= ucByte; |
| | | vSingleRst ^= vPassword[vKeyIndex]; |
| | | ucTemp = vSingleRst; |
| | | |
| | | vBuffer[i] = vSingleRst; |
| | | } |
| | | return vBuffer; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 配置加密密钥 |
| | | /// </summary> |
| | | void ConfigEncodeKey() |
| | | { |
| | | int vIndex = KeyEncodeIndex % gSendKeyDict.Length; |
| | | gSendKeyBytes = BitConverter.GetBytes((int)(gSendKeyDict[vIndex] ^ 153518004u)); |
| | | KeyEncodeIndex++; |
| | | } |
| | | |
| | | } |
copy from Utility/StringUtility.cs.meta
copy to Main/NetworkPackage/GameNetEncode.cs.meta
File was copied from Utility/StringUtility.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: c0960ed66238bdd49b70860dfee23488 |
| | | timeCreated: 1475005527 |
| | | guid: 60ade13afb439874889e483f8d22d3c1 |
| | | timeCreated: 1490778989 |
| | | licenseType: Free |
| | | MonoImporter: |
| | | serializedVersion: 2 |
New file |
| | |
| | | using UnityEngine; |
| | | using System.Collections; |
| | | using System; |
| | | using System.Text; |
| | | using System.Collections.Generic; |
| | | |
| | | /** 通迅包基类,处理字节流转换 */ |
| | | public class GameNetPackBasic |
| | | { |
| | | |
| | | public ServerType socketType = ServerType.Main; |
| | | |
| | | /** 协议号 */ |
| | | protected ushort _cmd = 0; |
| | | /** 协议号引用 */ |
| | | public ushort cmd { get { return _cmd; } } |
| | | /** 信息转换后的字节包 */ |
| | | protected byte[] _writedBytes; |
| | | /** 用于发送的组合帧 */ |
| | | protected byte[] _combineBytes; |
| | | /** 信息转换后的字节包的引用 */ |
| | | public byte[] dataBytes { get { return _writedBytes; } } |
| | | /** 用于发送的组合帧的引用 */ |
| | | public byte[] combineBytes { get { return _combineBytes; } } |
| | | /** 字节写入位置索引 */ |
| | | protected int _writeIndex = 0; |
| | | /** 解析位置索引 */ |
| | | protected int _readIndex = 2; |
| | | /** 最终合并采用的协议,为0表示不调整 */ |
| | | protected ushort combineCmd = 0; |
| | | /** 字符编码机 */ |
| | | public static Encoding StrEncoding = Encoding.UTF8; |
| | | |
| | | //自定义字段,用于后续更新用 |
| | | private Dictionary<string, object> fields; |
| | | |
| | | public void SetField(string key, object o) |
| | | { |
| | | if (fields == null) |
| | | fields = new Dictionary<string, object>(); |
| | | fields[key] = o; |
| | | } |
| | | |
| | | //获取自定义字段 |
| | | public T GetField<T>(string key) |
| | | { |
| | | if (fields == null) |
| | | { |
| | | Debug.LogErrorFormat("未设置自定义字段:{0}", key); |
| | | return default(T); |
| | | } |
| | | if (fields.TryGetValue(key, out object o)) |
| | | { |
| | | if (o is T) |
| | | return (T)o; |
| | | else |
| | | { |
| | | Debug.LogErrorFormat("自定义字段:{0},不是类型:{1}", key, typeof(T)); |
| | | return default(T); |
| | | } |
| | | } |
| | | Debug.LogErrorFormat("不存在自定义字段:{0}", key); |
| | | return default(T); |
| | | } |
| | | |
| | | |
| | | /** 子信息类型 */ |
| | | public enum NetDataType |
| | | { |
| | | BYTE, |
| | | WORD, |
| | | DWORD, |
| | | Chars, |
| | | Int, |
| | | Double |
| | | } |
| | | |
| | | /** 字符串长度写入的方式 */ |
| | | public enum StrWriteLen |
| | | { |
| | | BYTE, |
| | | WORD, |
| | | DWORD |
| | | } |
| | | |
| | | /** 字节占用字节量 */ |
| | | public static short ByteLeng = 1; |
| | | /** 布尔值占用字节量 */ |
| | | public static short BoolLeng = 1; |
| | | /** 短整型占用字节量 */ |
| | | public static short ShortLeng = 2; |
| | | /** 整型占用字节量 */ |
| | | public static short IntLeng = 4; |
| | | /** 长整型占用字节量 */ |
| | | public static short LongLeng = 8; |
| | | /** 双浮点型占用字节量 */ |
| | | public static short DoubleLeng = 8; |
| | | |
| | | /** 从字节包中解析信息 */ |
| | | public virtual void ReadFromBytes(byte[] vBytes) |
| | | { |
| | | |
| | | } |
| | | |
| | | /** 将信息写成字节包 */ |
| | | public virtual void WriteToBytes() |
| | | { |
| | | } |
| | | |
| | | private string _vInfoCont = ""; |
| | | public string vInfoCont { |
| | | get { |
| | | return _vInfoCont; |
| | | } |
| | | } |
| | | /** 组合帧信息 */ |
| | | public void CombineDatas(GameNetEncode encoder) |
| | | { |
| | | try |
| | | { |
| | | if (_writedBytes == null) |
| | | { |
| | | _writedBytes = new byte[0]; |
| | | } |
| | | |
| | | byte[] vCmdAndSubCmd = new byte[2]; |
| | | vCmdAndSubCmd[0] = (byte)((_cmd & 0xFF00) >> 8); |
| | | vCmdAndSubCmd[1] = (byte)(_cmd & 0xFF); |
| | | byte[] vCmdAndBody = new byte[_writedBytes.Length + vCmdAndSubCmd.Length]; // 协议与内容 |
| | | |
| | | //DesignDebug.NetLog("GameNetPackBasic vCmdAndBody:" + vCmdAndBody.Length); |
| | | Array.Copy(vCmdAndSubCmd, 0, vCmdAndBody, 0, vCmdAndSubCmd.Length); |
| | | if (_writedBytes.Length > 0) |
| | | Array.Copy(_writedBytes, 0, vCmdAndBody, vCmdAndSubCmd.Length, _writedBytes.Length); |
| | | |
| | | if (combineCmd != 0) // 采用另外的协议号 |
| | | { |
| | | byte[] vExCmdAndBody = new byte[vCmdAndBody.Length + 4]; |
| | | vExCmdAndBody[0] = (byte)((combineCmd & 0xFF00) >> 8); |
| | | vExCmdAndBody[1] = (byte)(combineCmd & 0xFF); |
| | | var _lengthBytes = BitConverter.GetBytes((ushort)vCmdAndBody.Length); |
| | | vExCmdAndBody[2] = _lengthBytes[0]; |
| | | vExCmdAndBody[3] = _lengthBytes[1]; |
| | | |
| | | Array.Copy(vCmdAndBody, 0, vExCmdAndBody, 4, vCmdAndBody.Length); |
| | | vCmdAndBody = vExCmdAndBody; |
| | | } |
| | | |
| | | vCmdAndBody = encoder.BaseXorAdd(vCmdAndBody); // 加密 |
| | | |
| | | _combineBytes = new byte[vCmdAndBody.Length + 6]; // 合并体 |
| | | byte[] vFrameHead = new byte[] { 255, 204 }; |
| | | byte[] vMsgBodyLength = BitConverter.GetBytes(vCmdAndBody.Length); |
| | | Array.Copy(vFrameHead, 0, _combineBytes, 0, vFrameHead.Length); |
| | | Array.Copy(vMsgBodyLength, 0, _combineBytes, 2, vMsgBodyLength.Length); |
| | | Array.Copy(vCmdAndBody, 0, _combineBytes, 6, vCmdAndBody.Length); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogFormat("封包信息组合异常 :{0}", ex); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** 转换字节段为布尔值 */ |
| | | protected void TransBytes(out bool vTof, byte[] vBytes, NetDataType vNetDataType) |
| | | { |
| | | try |
| | | { |
| | | vTof = false; |
| | | if (vNetDataType == NetDataType.BYTE) |
| | | { |
| | | if ((_readIndex + BoolLeng) <= vBytes.Length) |
| | | { |
| | | vTof = BitConverter.ToBoolean(vBytes, _readIndex); |
| | | _readIndex += BoolLeng; |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("(line:130) 字节包数据量不足"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("请指定正确的数据源类型"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogFormat("转换字节段为布尔值异常:{0}", ex); |
| | | vTof = false; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** 转换字节段为字节 */ |
| | | protected void TransBytes(out byte vbyte, byte[] vBytes, NetDataType vNetDataType) |
| | | { |
| | | try |
| | | { |
| | | vbyte = 0; |
| | | if (vNetDataType == NetDataType.BYTE) |
| | | { |
| | | if ((_readIndex + ByteLeng) <= vBytes.Length) |
| | | { |
| | | vbyte = vBytes[_readIndex]; |
| | | _readIndex += ByteLeng; |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("(line:189) 字节包数据量不足"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("请指定正确的数据源类型"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogFormat("转换字节段为字节异常:{0}", ex); |
| | | vbyte = 0; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** 转换字节段为短整型 */ |
| | | protected void TransBytes(out short vShort, byte[] vBytes, NetDataType vNetDataType) |
| | | { |
| | | try |
| | | { |
| | | vShort = 0; |
| | | if (vNetDataType == NetDataType.WORD) |
| | | { |
| | | if ((_readIndex + ShortLeng) <= vBytes.Length) |
| | | { |
| | | vShort = BitConverter.ToInt16(vBytes, _readIndex); |
| | | _readIndex += ShortLeng; |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError(" 字节包数据量不足"); |
| | | } |
| | | } |
| | | else if (vNetDataType == NetDataType.BYTE) |
| | | { |
| | | if ((_readIndex + ByteLeng) <= vBytes.Length) |
| | | { |
| | | byte vTheByte = vBytes[_readIndex]; |
| | | byte[] vTempBytes = new byte[2]; |
| | | vTempBytes[0] = vTheByte; |
| | | if (vTheByte > 127) |
| | | vTempBytes[1] = 0xFF; |
| | | vShort = BitConverter.ToInt16(vTempBytes, 0); |
| | | // DesignDebug.NetLog("vShort:" + vShort); |
| | | _readIndex += ByteLeng; |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError(" 字节包数据量不足"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("请指定正确的数据源类型"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogFormat("转换字节段为短整型异常:{0}", ex); |
| | | vShort = 0; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** 转换字节段为短整型 */ |
| | | protected void TransBytes(out ushort vShort, byte[] vBytes, NetDataType vNetDataType) |
| | | { |
| | | try |
| | | { |
| | | vShort = 0; |
| | | if (vNetDataType == NetDataType.WORD) |
| | | { |
| | | if ((_readIndex + ShortLeng) <= vBytes.Length) |
| | | { |
| | | vShort = BitConverter.ToUInt16(vBytes, _readIndex); |
| | | _readIndex += ShortLeng; |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("字节包数据量不足"); |
| | | } |
| | | } |
| | | else if (vNetDataType == NetDataType.BYTE) |
| | | { |
| | | if ((_readIndex + ByteLeng) <= vBytes.Length) |
| | | { |
| | | vShort = (ushort)vBytes[_readIndex]; |
| | | _readIndex += ByteLeng; |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("字节包数据量不足"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("请指定正确的数据源类型"); |
| | | } |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogFormat("转换字节段为短整型异常:{0}", ex); |
| | | vShort = 0; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** 转换字节段为整型 */ |
| | | protected void TransBytes(out int vInt, byte[] vBytes, NetDataType vNetDataType) |
| | | { |
| | | try |
| | | { |
| | | vInt = 0; |
| | | if (vNetDataType == NetDataType.DWORD || vNetDataType == NetDataType.Int) |
| | | { |
| | | if ((_readIndex + IntLeng) <= vBytes.Length) |
| | | { |
| | | vInt = BitConverter.ToInt32(vBytes, _readIndex); |
| | | _readIndex += IntLeng; |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("字节包数据量不足"); |
| | | } |
| | | |
| | | } |
| | | else if (vNetDataType == NetDataType.BYTE) |
| | | { |
| | | vInt = (int)vBytes[_readIndex]; |
| | | _readIndex += 1; |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("请指定正确的数据源类型"); |
| | | } |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogFormat("转换字节段为整型异常:{0}", ex); |
| | | vInt = 0; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** 转换字节段为整型 */ |
| | | protected void TransBytes(out uint vInt, byte[] vBytes, NetDataType vNetDataType) |
| | | { |
| | | try |
| | | { |
| | | vInt = 0; |
| | | if (vNetDataType == NetDataType.DWORD || vNetDataType == NetDataType.Int) |
| | | { |
| | | if ((_readIndex + IntLeng) <= vBytes.Length) |
| | | { |
| | | vInt = BitConverter.ToUInt32(vBytes, _readIndex); |
| | | _readIndex += IntLeng; |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("(line:228) 字节包数据量不足"); |
| | | } |
| | | } |
| | | else if (vNetDataType == NetDataType.WORD) |
| | | { |
| | | if ((_readIndex + ShortLeng) <= vBytes.Length) |
| | | { |
| | | vInt = (uint)BitConverter.ToUInt16(vBytes, _readIndex); |
| | | _readIndex += ShortLeng; |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("(line:238) 字节包数据量不足"); |
| | | } |
| | | } |
| | | else if (vNetDataType == NetDataType.BYTE) |
| | | { |
| | | vInt = (uint)vBytes[_readIndex]; |
| | | _readIndex += 1; |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("请指定正确的数据源类型"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogFormat("转换字节段为整型异常:{0}", ex); |
| | | vInt = 0; |
| | | } |
| | | |
| | | } |
| | | |
| | | protected void TransBytes(out byte[] bytes, byte[] vBytes, NetDataType vNetDataType, byte vLeng) |
| | | { |
| | | TransBytes(out bytes, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | protected void TransBytes(out byte[] bytes, byte[] vBytes, NetDataType vNetDataType, ushort vLeng) |
| | | { |
| | | TransBytes(out bytes, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | protected void TransBytes(out byte[] bytes, byte[] vBytes, NetDataType vNetDataType, short vLeng) |
| | | { |
| | | TransBytes(out bytes, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | protected void TransBytes(out byte[] bytes, byte[] vBytes, NetDataType vNetDataType, uint vLeng) |
| | | { |
| | | TransBytes(out bytes, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | protected void TransBytes(out byte[] bytes, byte[] vBytes, NetDataType vNetDataType, int vLeng) |
| | | { |
| | | try |
| | | { |
| | | bytes = new byte[vLeng]; |
| | | if (vNetDataType == NetDataType.BYTE) |
| | | { |
| | | if ((_readIndex + ByteLeng) <= vBytes.Length) |
| | | { |
| | | for (int i = 0; i < vLeng; i++) |
| | | { |
| | | bytes[i] = vBytes[_readIndex]; |
| | | _readIndex += ByteLeng; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("字节包数据量不足"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("请指定正确的数据源类型"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogFormat("转换字节段为字节数组异常:{0}", ex); |
| | | bytes = null; |
| | | } |
| | | |
| | | } |
| | | |
| | | protected void TransBytes(out ushort[] uShorts, byte[] vBytes, NetDataType vNetDataType, byte vLeng) |
| | | { |
| | | TransBytes(out uShorts, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | protected void TransBytes(out ushort[] uShorts, byte[] vBytes, NetDataType vNetDataType, short vLeng) |
| | | { |
| | | TransBytes(out uShorts, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | protected void TransBytes(out ushort[] uShorts, byte[] vBytes, NetDataType vNetDataType, ushort vLeng) |
| | | { |
| | | TransBytes(out uShorts, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | protected void TransBytes(out ushort[] uShorts, byte[] vBytes, NetDataType vNetDataType, uint vLeng) |
| | | { |
| | | TransBytes(out uShorts, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | protected void TransBytes(out ushort[] uShorts, byte[] vBytes, NetDataType vNetDataType, int vLeng) |
| | | { |
| | | try |
| | | { |
| | | uShorts = new ushort[vLeng]; |
| | | if (vNetDataType == NetDataType.WORD) |
| | | { |
| | | if ((_readIndex + ShortLeng) <= vBytes.Length) |
| | | { |
| | | for (int i = 0; i < vLeng; i++) |
| | | { |
| | | uShorts[i] = BitConverter.ToUInt16(vBytes, _readIndex); |
| | | _readIndex += ShortLeng; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("(line:179) 字节包数据量不足"); |
| | | } |
| | | } |
| | | else if (vNetDataType == NetDataType.BYTE) |
| | | { |
| | | if ((_readIndex + ByteLeng) <= vBytes.Length) |
| | | { |
| | | for (int i = 0; i < vLeng; i++) |
| | | { |
| | | uShorts[i] = (ushort)vBytes[_readIndex]; |
| | | _readIndex += ByteLeng; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("(line:189) 字节包数据量不足"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("请指定正确的数据源类型"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogFormat("转换字节段为短整型数组异常:{0}", ex); |
| | | uShorts = null; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** 转换字节段为短整型数组 */ |
| | | protected void TransBytes(out short[] vShorts, byte[] vBytes, NetDataType vNetDataType, byte vLeng) |
| | | { |
| | | TransBytes(out vShorts, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | /** 转换字节段为短整型数组 */ |
| | | protected void TransBytes(out short[] vShorts, byte[] vBytes, NetDataType vNetDataType, short vLeng) |
| | | { |
| | | TransBytes(out vShorts, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | protected void TransBytes(out short[] vShorts, byte[] vBytes, NetDataType vNetDataType, ushort vLeng) |
| | | { |
| | | TransBytes(out vShorts, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | protected void TransBytes(out short[] vShorts, byte[] vBytes, NetDataType vNetDataType, uint vLeng) |
| | | { |
| | | TransBytes(out vShorts, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | /** 转换字节段为短整型数组 */ |
| | | protected void TransBytes(out short[] vShorts, byte[] vBytes, NetDataType vNetDataType, int vLeng) |
| | | { |
| | | try |
| | | { |
| | | vShorts = new short[vLeng]; |
| | | if (vLeng > 0) |
| | | { |
| | | if (vNetDataType == NetDataType.WORD) |
| | | { |
| | | for (int i = 0; i < vLeng; i++) |
| | | { |
| | | vShorts[i] = (short)BitConverter.ToInt16(vBytes, _readIndex); |
| | | _readIndex += ShortLeng; |
| | | } |
| | | } |
| | | else if (vNetDataType == NetDataType.BYTE) |
| | | { |
| | | byte vTheByte; |
| | | byte[] vTempBytes; |
| | | for (int i = 0; i < vLeng; i++) |
| | | { |
| | | vTheByte = vBytes[i]; |
| | | vTempBytes = new byte[2]; |
| | | vTempBytes[0] = vTheByte; |
| | | if (vTheByte > 127) |
| | | vTempBytes[1] = 0xFF; |
| | | vShorts[i] = BitConverter.ToInt16(vTempBytes, 0); |
| | | _readIndex += ByteLeng; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("请指定正确的数据源类型"); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogFormat("转换字节段为短整型数组异常:{0}", ex); |
| | | vShorts = null; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** 转换字节段为整型数组 */ |
| | | protected void TransBytes(out int[] vInts, byte[] vBytes, NetDataType vNetDataType, byte vLeng) |
| | | { |
| | | TransBytes(out vInts, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | /** 转换字节段为整型数组 */ |
| | | protected void TransBytes(out int[] vInts, byte[] vBytes, NetDataType vNetDataType, short vLeng) |
| | | { |
| | | TransBytes(out vInts, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | /** 转换字节段为整型数组 */ |
| | | protected void TransBytes(out int[] vInts, byte[] vBytes, NetDataType vNetDataType, ushort vLeng) |
| | | { |
| | | TransBytes(out vInts, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | /** 转换字节段为整型数组 */ |
| | | protected void TransBytes(out int[] vInts, byte[] vBytes, NetDataType vNetDataType, uint vLeng) |
| | | { |
| | | TransBytes(out vInts, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | /** 转换字节段为整型数组 */ |
| | | protected void TransBytes(out int[] vInts, byte[] vBytes, NetDataType vNetDataType, int vLeng) |
| | | { |
| | | try |
| | | { |
| | | vInts = new int[vLeng]; |
| | | if (vLeng > 0) |
| | | { |
| | | if (vNetDataType == NetDataType.DWORD || vNetDataType == NetDataType.Int) |
| | | { |
| | | for (int i = 0; i < vLeng; i++) |
| | | { |
| | | vInts[i] = (int)BitConverter.ToInt32(vBytes, _readIndex); |
| | | _readIndex += IntLeng; |
| | | } |
| | | } |
| | | else if (vNetDataType == NetDataType.WORD) |
| | | { |
| | | for (int i = 0; i < vLeng; i++) |
| | | { |
| | | vInts[i] = (int)BitConverter.ToInt16(vBytes, _readIndex); |
| | | _readIndex += ShortLeng; |
| | | } |
| | | } |
| | | else if (vNetDataType == NetDataType.BYTE) |
| | | { |
| | | for (int i = 0; i < vLeng; i++) |
| | | { |
| | | vInts[i] = (int)vBytes[i]; |
| | | _readIndex += ByteLeng; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("请指定正确的数据源类型"); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogFormat("转换字节段为整型数组异常:{0}", ex); |
| | | vInts = null; |
| | | } |
| | | |
| | | } |
| | | |
| | | protected void TransBytes(out uint[] uInts, byte[] vBytes, NetDataType vNetDataType, byte vLeng) |
| | | { |
| | | TransBytes(out uInts, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | protected void TransBytes(out uint[] uInts, byte[] vBytes, NetDataType vNetDataType, short vLeng) |
| | | { |
| | | TransBytes(out uInts, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | protected void TransBytes(out uint[] uInts, byte[] vBytes, NetDataType vNetDataType, ushort vLeng) |
| | | { |
| | | TransBytes(out uInts, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | protected void TransBytes(out uint[] uInts, byte[] vBytes, NetDataType vNetDataType, uint vLeng) |
| | | { |
| | | TransBytes(out uInts, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | protected void TransBytes(out uint[] uInts, byte[] vBytes, NetDataType vNetDataType, int vLeng) |
| | | { |
| | | try |
| | | { |
| | | uInts = new uint[vLeng]; |
| | | if (vLeng > 0) |
| | | { |
| | | if (vNetDataType == NetDataType.DWORD || vNetDataType == NetDataType.Int) |
| | | { |
| | | for (int i = 0; i < vLeng; i++) |
| | | { |
| | | uInts[i] = (uint)BitConverter.ToUInt32(vBytes, _readIndex); |
| | | _readIndex += IntLeng; |
| | | } |
| | | } |
| | | else if (vNetDataType == NetDataType.WORD) |
| | | { |
| | | for (int i = 0; i < vLeng; i++) |
| | | { |
| | | uInts[i] = (uint)BitConverter.ToUInt16(vBytes, _readIndex); |
| | | _readIndex += ShortLeng; |
| | | } |
| | | } |
| | | else if (vNetDataType == NetDataType.BYTE) |
| | | { |
| | | for (int i = 0; i < vLeng; i++) |
| | | { |
| | | uInts[i] = (uint)vBytes[i]; |
| | | _readIndex += ByteLeng; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("请指定正确的数据源类型"); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogFormat("转换字节段为无符号整型数组异常:{0}", ex); |
| | | uInts = null; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** 转换字节段为Double型数据 */ |
| | | protected void TransBytes(out double vDouble, byte[] vBytes, NetDataType vNetDataType) |
| | | { |
| | | try |
| | | { |
| | | vDouble = 0; |
| | | if (vNetDataType == NetDataType.Double) |
| | | { |
| | | if ((_readIndex + DoubleLeng) <= vBytes.Length) |
| | | { |
| | | vDouble = BitConverter.ToDouble(vBytes, _readIndex); |
| | | _readIndex += DoubleLeng; |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("(line:341) 字节包数据量不足"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("请指定正确的数据源类型"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogFormat("转换字节段为Double型数据异常:{0}", ex); |
| | | vDouble = 0; |
| | | } |
| | | |
| | | } |
| | | |
| | | protected void TransBytes(out string vStr, byte[] vBytes, NetDataType vNetDataType, byte vLeng) |
| | | { |
| | | TransBytes(out vStr, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | /** 转换字节段为字符串 */ |
| | | protected void TransBytes(out string vStr, byte[] vBytes, NetDataType vNetDataType, ushort vLeng) |
| | | { |
| | | TransBytes(out vStr, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | /** 转换字节段为字符串 */ |
| | | protected void TransBytes(out string vStr, byte[] vBytes, NetDataType vNetDataType, uint vLeng) |
| | | { |
| | | TransBytes(out vStr, vBytes, vNetDataType, (int)vLeng); |
| | | } |
| | | |
| | | /** 转换字节段为字符串 */ |
| | | protected void TransBytes(out string vStr, byte[] vBytes, NetDataType vNetDataType, int vLeng) |
| | | { |
| | | try |
| | | { |
| | | vStr = ""; |
| | | if (vLeng == 0) |
| | | return; |
| | | if (vNetDataType == NetDataType.Chars) |
| | | { |
| | | if ((_readIndex + vLeng) <= vBytes.Length) |
| | | { |
| | | vStr = StrEncoding.GetString(vBytes, _readIndex, vLeng); |
| | | _readIndex += vLeng; |
| | | } |
| | | else |
| | | { |
| | | Debug.LogErrorFormat("(line:365) 字节包数据量不足: _readIndex {0}, vLeng {1}, vBytes.Length {2}", _readIndex, vLeng, vBytes.Length); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Debug.LogError("请指定正确的数据源类型"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogFormat("转换字节段为字符串异常:{0}", ex); |
| | | vStr = string.Empty; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** 转换布尔值为字节 */ |
| | | protected void WriteBytes(bool vTof, NetDataType vType) |
| | | { |
| | | this.WriteBytes(BitConverter.GetBytes(vTof)); |
| | | } |
| | | |
| | | /** 转换短整型为字节 */ |
| | | protected void WriteBytes(short vShort, NetDataType vType) |
| | | { |
| | | this.WriteBytes((int)vShort, vType); |
| | | } |
| | | |
| | | /** 以固定的字节长度转短整型数值数组为字节 */ |
| | | protected void WriteBytes(short[] vShorts, NetDataType vType, int vLockLeng) |
| | | { |
| | | this.WriteBytes(ShortsToInts(vShorts), vType, vLockLeng); |
| | | } |
| | | |
| | | /** 以固定的字节长度转短整型数值数组为字节 */ |
| | | protected void WriteBytes(ushort[] uShorts, NetDataType vType, int vLockLeng) |
| | | { |
| | | this.WriteBytes(UShortsToInts(uShorts), vType, vLockLeng); |
| | | } |
| | | |
| | | /** 以固定的字节长度转字节数组为字节 */ |
| | | protected void WriteBytes(byte[] bytes, NetDataType vType, int vLockLeng) |
| | | { |
| | | this.WriteBytes(BytesToInts(bytes), vType, vLockLeng); |
| | | } |
| | | |
| | | /** 转短整型数值数组为字节 */ |
| | | protected void WriteBytes(short[] vShorts, NetDataType vType, StrWriteLen vWriteLen) |
| | | { |
| | | this.WriteBytes(ShortsToInts(vShorts), vType, vWriteLen); |
| | | } |
| | | |
| | | /** 无符号短整数组转整型数组 */ |
| | | private int[] UShortsToInts(ushort[] uShorts) |
| | | { |
| | | try |
| | | { |
| | | int l = uShorts.Length; |
| | | int[] vInts = new int[l]; |
| | | int i; |
| | | for (i = 0; i < l; i++) |
| | | vInts[i] = (int)uShorts[i]; |
| | | return vInts; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** 短整数组转整型数组 */ |
| | | private int[] ShortsToInts(short[] vShorts) |
| | | { |
| | | try |
| | | { |
| | | int l = vShorts.Length; |
| | | int[] vInts = new int[l]; |
| | | int i; |
| | | for (i = 0; i < l; i++) |
| | | vInts[i] = (int)vShorts[i]; |
| | | return vInts; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** 字节数组转整型数组 */ |
| | | private int[] BytesToInts(byte[] bytes) |
| | | { |
| | | try |
| | | { |
| | | if (bytes != null) |
| | | { |
| | | int l = bytes.Length; |
| | | int[] vInts = new int[l]; |
| | | int i; |
| | | for (i = 0; i < l; i++) |
| | | vInts[i] = (int)bytes[i]; |
| | | return vInts; |
| | | } |
| | | else |
| | | { |
| | | int[] vInts = new int[0]; |
| | | return vInts; |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** 转换整型为字节 */ |
| | | protected void WriteBytes(int vInt, NetDataType vType) |
| | | { |
| | | try |
| | | { |
| | | byte[] vRst; |
| | | if (vType == NetDataType.WORD) |
| | | vRst = BitConverter.GetBytes((short)vInt); |
| | | else if (vType == NetDataType.BYTE) |
| | | { |
| | | vRst = new byte[1]; |
| | | vRst[0] = (byte)(vInt & 0xFF); // BitConverter.GetBytes ((byte)vInt); |
| | | } |
| | | else |
| | | vRst = BitConverter.GetBytes((int)vInt); |
| | | this.WriteBytes(vRst); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | } |
| | | |
| | | protected void WriteBytes(uint[] vInts, NetDataType vType, int vLockLeng) |
| | | { |
| | | try |
| | | { |
| | | if (vInts.Length != vLockLeng) |
| | | Array.Resize(ref vInts, vLockLeng); |
| | | this.WriteBytes(vInts, vType); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** 约束数组长度并转为字节段,不写入长度 */ |
| | | protected void WriteBytes(int[] vInts, NetDataType vType, int vLockLeng) |
| | | { |
| | | try |
| | | { |
| | | if (vInts.Length != vLockLeng) |
| | | Array.Resize(ref vInts, vLockLeng); |
| | | this.WriteBytes(vInts, vType); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | } |
| | | |
| | | /** 整型数组转为字节段,以指定的数据类型写入长度 */ |
| | | protected void WriteBytes(int[] vInts, NetDataType vType, StrWriteLen vWriteLen) |
| | | { |
| | | try |
| | | { |
| | | if (vWriteLen == StrWriteLen.BYTE) |
| | | this.WriteBytes(new Byte[] { (byte)vInts.Length }); |
| | | else if (vWriteLen == StrWriteLen.WORD) |
| | | this.WriteBytes(BitConverter.GetBytes((short)vInts.Length)); |
| | | else |
| | | this.WriteBytes(BitConverter.GetBytes((int)vInts.Length)); |
| | | this.WriteBytes(vInts, vType); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | } |
| | | |
| | | /** 转整型数值数组为字节 */ |
| | | private void WriteBytes(uint[] vInts, NetDataType vType) |
| | | { |
| | | try |
| | | { |
| | | int l = vInts.Length; |
| | | byte[] vRst; |
| | | int i; |
| | | int vBytesLen; |
| | | if (vType == NetDataType.BYTE) |
| | | { |
| | | vBytesLen = l; |
| | | vRst = new byte[vBytesLen]; |
| | | for (i = 0; i < l; i++) |
| | | Array.Copy(BitConverter.GetBytes((byte)vInts[i]), 0, vRst, i, 1); |
| | | } |
| | | else if (vType == NetDataType.WORD) |
| | | { |
| | | vBytesLen = l * 2; |
| | | vRst = new byte[vBytesLen]; |
| | | for (i = 0; i < l; i++) |
| | | Array.Copy(BitConverter.GetBytes((short)vInts[i]), 0, vRst, i * 2, 2); |
| | | } |
| | | else |
| | | { |
| | | vBytesLen = l * 4; |
| | | vRst = new byte[vBytesLen]; |
| | | for (i = 0; i < l; i++) |
| | | Array.Copy(BitConverter.GetBytes((int)vInts[i]), 0, vRst, i * 4, 4); |
| | | } |
| | | this.WriteBytes(vRst); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** 转整型数值数组为字节 */ |
| | | private void WriteBytes(int[] vInts, NetDataType vType) |
| | | { |
| | | try |
| | | { |
| | | int l = vInts.Length; |
| | | byte[] vRst; |
| | | int i; |
| | | int vBytesLen; |
| | | if (vType == NetDataType.BYTE) |
| | | { |
| | | vBytesLen = l; |
| | | vRst = new byte[vBytesLen]; |
| | | for (i = 0; i < l; i++) |
| | | Array.Copy(BitConverter.GetBytes((byte)vInts[i]), 0, vRst, i, 1); |
| | | } |
| | | else if (vType == NetDataType.WORD) |
| | | { |
| | | vBytesLen = l * 2; |
| | | vRst = new byte[vBytesLen]; |
| | | for (i = 0; i < l; i++) |
| | | Array.Copy(BitConverter.GetBytes((short)vInts[i]), 0, vRst, i * 2, 2); |
| | | } |
| | | else |
| | | { |
| | | vBytesLen = l * 4; |
| | | vRst = new byte[vBytesLen]; |
| | | for (i = 0; i < l; i++) |
| | | Array.Copy(BitConverter.GetBytes((int)vInts[i]), 0, vRst, i * 4, 4); |
| | | } |
| | | this.WriteBytes(vRst); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** 转换双精度数值为字节段 */ |
| | | protected void WriteBytes(uint vuint, NetDataType vType) |
| | | { |
| | | try |
| | | { |
| | | byte[] vRst; |
| | | vRst = BitConverter.GetBytes(vuint); |
| | | this.WriteBytes(vRst); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | } |
| | | |
| | | /** 转换字符串为字节段,byte量定长型,不写入长度 */ |
| | | protected void WriteBytes(string vStr, NetDataType vType, int vShortLen) |
| | | { |
| | | if (vStr == null) |
| | | { |
| | | vStr = string.Empty; |
| | | } |
| | | try |
| | | { |
| | | byte[] vRst = StrEncoding.GetBytes(vStr); |
| | | if (vRst.Length != vShortLen) |
| | | Array.Resize(ref vRst, vShortLen); |
| | | this.WriteBytes(vRst); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** 转换字符串为字节段,动长型,前置写入长度 */ |
| | | protected void WriteBytes(string vStr, NetDataType vType, StrWriteLen vWriteLen) |
| | | { |
| | | try |
| | | { |
| | | byte[] vRst = StrEncoding.GetBytes(vStr); |
| | | if (vWriteLen == StrWriteLen.BYTE) |
| | | this.WriteBytes(new Byte[] { (byte)vRst.Length }); |
| | | else if (vWriteLen == StrWriteLen.WORD) |
| | | this.WriteBytes(BitConverter.GetBytes((short)vRst.Length)); |
| | | else |
| | | this.WriteBytes(BitConverter.GetBytes((int)vRst.Length)); |
| | | this.WriteBytes(vRst); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** 写入一段字节数据 */ |
| | | private void WriteBytes(byte[] vBytes) |
| | | { |
| | | try |
| | | { |
| | | Array.Resize(ref _writedBytes, _writeIndex + vBytes.Length); |
| | | vBytes.CopyTo(_writedBytes, _writeIndex); |
| | | _writeIndex = _writedBytes.Length; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | } |
| | | |
| | | } |
File was renamed from Utility/StringUtility.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: c0960ed66238bdd49b70860dfee23488 |
| | | timeCreated: 1475005527 |
| | | guid: d2428e8224ba4d247a3aab84b19aaa9b |
| | | timeCreated: 1490779004 |
| | | licenseType: Free |
| | | MonoImporter: |
| | | serializedVersion: 2 |
New file |
| | |
| | | using UnityEngine; |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | |
| | | |
| | | public class GameNetSystem : Singleton<GameNetSystem> |
| | | { |
| | | // NetUpdateBehaviour m_NetUpdateBehaviour; |
| | | NeverConnectState neverConnectState; |
| | | AccountLoginState accountLoginState; |
| | | // CreateOrSelectRoleState createOrSelectRoleState; |
| | | RoleLoginState roleLoginState; |
| | | ConnectedState connectedState; |
| | | DisconnectState disconnectState; |
| | | |
| | | NetState m_NetState; |
| | | public NetState netState |
| | | { |
| | | get { return this.m_NetState; } |
| | | set |
| | | { |
| | | if (this.m_NetState != value) |
| | | { |
| | | switch (m_NetState) |
| | | { |
| | | case NetState.NerverConnect: |
| | | neverConnectState.OnExit(); |
| | | break; |
| | | case NetState.AccountLogin: |
| | | accountLoginState.OnExit(); |
| | | break; |
| | | case NetState.CreateOrSelectRole: |
| | | // createOrSelectRoleState.OnExit(); |
| | | break; |
| | | case NetState.RoleLogin: |
| | | roleLoginState.OnExit(); |
| | | break; |
| | | case NetState.Connected: |
| | | connectedState.OnExit(); |
| | | break; |
| | | case NetState.DisConnected: |
| | | disconnectState.OnExit(); |
| | | break; |
| | | } |
| | | |
| | | this.m_NetState = value; |
| | | switch (m_NetState) |
| | | { |
| | | case NetState.NerverConnect: |
| | | neverConnectState.OnEnter(); |
| | | break; |
| | | case NetState.AccountLogin: |
| | | accountLoginState.OnEnter(); |
| | | break; |
| | | case NetState.CreateOrSelectRole: |
| | | // createOrSelectRoleState.OnEnter(); |
| | | break; |
| | | case NetState.RoleLogin: |
| | | roleLoginState.OnEnter(); |
| | | break; |
| | | case NetState.Connected: |
| | | connectedState.OnEnter(); |
| | | break; |
| | | case NetState.DisConnected: |
| | | disconnectState.OnEnter(); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | private ClientSocket mainSocket; |
| | | public bool mainSocketConnected { get { return mainSocket == null ? false : mainSocket.connected; } } |
| | | |
| | | public float timeSinceMainSocketLastProtocol |
| | | { |
| | | get { return mainSocket == null ? Time.time : (float)(DateTime.Now - mainSocket.lastPackageTime).TotalSeconds; } |
| | | } |
| | | |
| | | public bool crossServerConnected_Loigc { get; set; } |
| | | private ClientSocket crossServerSocket; |
| | | public bool crossServerSocketConnected { get { return crossServerConnected_Loigc && (crossServerSocket == null ? false : crossServerSocket.connected); } } |
| | | |
| | | public float timeSinceCrossServerSocketLastProtocol |
| | | { |
| | | get { return crossServerSocket == null ? Time.time : (float)(DateTime.Now - crossServerSocket.lastPackageTime).TotalSeconds; } |
| | | } |
| | | |
| | | Queue<GameNetPackBasic> mainProtocolQueue = new Queue<GameNetPackBasic>(); |
| | | Queue<GameNetPackBasic> crossSeverProtocolQueue = new Queue<GameNetPackBasic>(); |
| | | |
| | | public CrossServerData crossServerData { get; private set; } |
| | | |
| | | public GameNetSystem() |
| | | { |
| | | var gameObject = new GameObject("NetUpdateBehaviour"); |
| | | GameObject.DontDestroyOnLoad(gameObject); |
| | | // m_NetUpdateBehaviour = gameObject.AddComponent<NetUpdateBehaviour>(); |
| | | // m_NetUpdateBehaviour.RegisterUpdateCallBack(OnUpdate); |
| | | |
| | | neverConnectState = gameObject.AddComponent<NeverConnectState>(); |
| | | accountLoginState = gameObject.AddComponent<AccountLoginState>(); |
| | | // createOrSelectRoleState = gameObject.AddComponent<CreateOrSelectRoleState>(); |
| | | roleLoginState = gameObject.AddComponent<RoleLoginState>(); |
| | | connectedState = gameObject.AddComponent<ConnectedState>(); |
| | | disconnectState = gameObject.AddComponent<DisconnectState>(); |
| | | |
| | | netState = NetState.NerverConnect; |
| | | } |
| | | |
| | | public void BeginConnectGameServer(string ip, int port, Action<bool> onConnected) |
| | | { |
| | | try |
| | | { |
| | | if (mainSocketConnected) |
| | | { |
| | | mainSocket.CloseConnect(); |
| | | } |
| | | } |
| | | catch (System.Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | |
| | | mainSocket = new ClientSocket(ServerType.Main); |
| | | mainProtocolQueue.Clear(); |
| | | |
| | | mainSocket.Connect(ip, port, (bool ok) => |
| | | { |
| | | if (onConnected != null) |
| | | { |
| | | onConnected(ok); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | public void BeginConnectCrossServer(string ip, int port, Action<bool> onConnected) |
| | | { |
| | | try |
| | | { |
| | | crossServerConnected_Loigc = false; |
| | | if (crossServerSocketConnected) |
| | | { |
| | | crossServerSocket.CloseConnect(); |
| | | } |
| | | } |
| | | catch (System.Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | |
| | | crossServerSocket = new ClientSocket(ServerType.CrossSever); |
| | | crossSeverProtocolQueue.Clear(); |
| | | this.crossServerSocket.Connect(ip, port, (bool ok) => |
| | | { |
| | | if (onConnected != null) |
| | | { |
| | | onConnected(ok); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | public void UpdateCrossServerData(string ip, int port, byte state) |
| | | { |
| | | this.crossServerData = new CrossServerData(ip, port, state); |
| | | if (this.crossServerData.crossState == 0) |
| | | { |
| | | crossServerConnected_Loigc = false; |
| | | } |
| | | } |
| | | |
| | | public void SendInfo(GameNetPackBasic protocol) |
| | | { |
| | | if (mainSocket != null) |
| | | { |
| | | mainSocket.SendInfo(protocol); |
| | | DebugPkgCache.Push(protocol); |
| | | } |
| | | } |
| | | |
| | | public void SendInfo(byte[] vBytes) |
| | | { |
| | | if (mainSocket != null) |
| | | { |
| | | mainSocket.SendInfo(vBytes); |
| | | } |
| | | } |
| | | |
| | | public void SendToCrossServer(GameNetPackBasic protocol) |
| | | { |
| | | if (crossServerSocket != null) |
| | | { |
| | | protocol.socketType = ServerType.CrossSever; |
| | | crossServerSocket.SendInfo(protocol); |
| | | DebugPkgCache.Push(protocol); |
| | | } |
| | | } |
| | | |
| | | public void PushPackage(GameNetPackBasic protocol, ServerType type) |
| | | { |
| | | lock (this) |
| | | { |
| | | if (protocol == null) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | if (PackageRegedit.Contain(protocol.cmd)) |
| | | { |
| | | switch (type) |
| | | { |
| | | case ServerType.Main: |
| | | mainProtocolQueue.Enqueue(protocol); |
| | | break; |
| | | case ServerType.CrossSever: |
| | | crossSeverProtocolQueue.Enqueue(protocol); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | DebugPkgCache.Push(protocol); |
| | | } |
| | | else |
| | | { |
| | | Debug.LogErrorFormat("数据包(cmd:{0})未登记!", protocol.cmd); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public void Disconnect() |
| | | { |
| | | try |
| | | { |
| | | if (mainSocket != null) |
| | | { |
| | | mainSocket.CloseConnect(); |
| | | } |
| | | |
| | | if (crossServerSocket != null) |
| | | { |
| | | crossServerSocket.CloseConnect(); |
| | | } |
| | | |
| | | mainProtocolQueue.Clear(); |
| | | crossSeverProtocolQueue.Clear(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | finally |
| | | { |
| | | netState = NetState.DisConnected; |
| | | // var loginModel = ModelCenter.Instance.GetModel<LoginModel>(); |
| | | // loginModel.busy = false; |
| | | // CrossServerLogin.Instance.busy = false; |
| | | } |
| | | } |
| | | |
| | | public void DisconnectCrossServer() |
| | | { |
| | | try |
| | | { |
| | | if (crossServerSocket != null) |
| | | { |
| | | crossServerSocket.CloseConnect(); |
| | | } |
| | | |
| | | crossSeverProtocolQueue.Clear(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | finally |
| | | { |
| | | // CrossServerLogin.Instance.busy = false; |
| | | } |
| | | } |
| | | |
| | | public void Reconnect() |
| | | { |
| | | try |
| | | { |
| | | if (mainSocket != null) |
| | | { |
| | | mainSocket.CloseConnect(); |
| | | } |
| | | |
| | | if (crossServerSocket != null) |
| | | { |
| | | crossServerSocket.CloseConnect(); |
| | | } |
| | | |
| | | mainProtocolQueue.Clear(); |
| | | crossSeverProtocolQueue.Clear(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | finally |
| | | { |
| | | netState = NetState.AccountLogin; |
| | | // CrossServerLogin.Instance.busy = false; |
| | | // var loginModel = ModelCenter.Instance.GetModel<LoginModel>(); |
| | | // loginModel.busy = false; |
| | | // loginModel.ReAccountLogin(); |
| | | } |
| | | } |
| | | |
| | | public void LoginOut() |
| | | { |
| | | // if (CameraController.Instance != null) |
| | | // CameraController.Instance.SetInGame(false); |
| | | // DTC0102_tagCDBPlayer.isAfterPlayerDataInitialize = false; |
| | | |
| | | try |
| | | { |
| | | // ynmbxxjUtil.Instance.RoleLoginOut(); |
| | | crossServerConnected_Loigc = false; |
| | | |
| | | if (mainSocket != null) |
| | | { |
| | | mainSocket.CloseConnect(); |
| | | } |
| | | |
| | | if (crossServerSocket != null) |
| | | { |
| | | crossServerSocket.CloseConnect(); |
| | | } |
| | | |
| | | mainProtocolQueue.Clear(); |
| | | crossSeverProtocolQueue.Clear(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | finally |
| | | { |
| | | netState = NetState.NerverConnect; |
| | | // CrossServerLogin.Instance.busy = false; |
| | | // //ArenaManager.isArenaClient = false; |
| | | // var loginModel = ModelCenter.Instance.GetModel<LoginModel>(); |
| | | // loginModel.busy = false; |
| | | // WindowJumpMgr.Instance.ClearJumpData(); |
| | | |
| | | // StageLoad.Instance.PushSceneLoadCommand(new StageLoad.StageLoadCommand() |
| | | // { |
| | | // toMapId = 1, |
| | | // toLineId = 0, |
| | | // needEmpty = false, |
| | | // needLoadResource = true, |
| | | // serverType = ServerType.Main, |
| | | // isClientLoadMap = true |
| | | // }); |
| | | // //CameraManager.uiCamera.clearFlags = CameraClearFlags.SolidColor; |
| | | // //GameObject obj = GameObject.Find("NormalCanvas"); |
| | | // //int count = obj.transform.childCount; |
| | | // //for (int i = count - 1; i >= 0; --i) |
| | | // //{ |
| | | // // //Debug.LogError(obj.transform.GetChild(i).name); |
| | | // // GameObject.Destroy(obj.transform.GetChild(i).gameObject); |
| | | // //} |
| | | // //SceneManager.LoadScene("Empty"); |
| | | // NetLinkWin.Hide(); |
| | | // DTC0403_tagPlayerLoginLoadOK.neverLoginOk = true; |
| | | } |
| | | } |
| | | |
| | | public void OnAccountLogin() |
| | | { |
| | | netState = NetState.AccountLogin; |
| | | } |
| | | |
| | | public void OnEnterWorld() |
| | | { |
| | | netState = NetState.RoleLogin; |
| | | } |
| | | |
| | | void OnUpdate() |
| | | { |
| | | lock (this) |
| | | { |
| | | while (mainProtocolQueue.Count > 0) |
| | | { |
| | | var package = mainProtocolQueue.Dequeue(); |
| | | if (package != null) |
| | | { |
| | | PackageRegedit.Distribute(package); |
| | | } |
| | | } |
| | | while (crossSeverProtocolQueue.Count > 0) |
| | | { |
| | | var package = crossSeverProtocolQueue.Dequeue(); |
| | | if (package != null) |
| | | { |
| | | PackageRegedit.Distribute(package); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | public enum NetState |
| | | { |
| | | NerverConnect = 1, |
| | | AccountLogin = 2, |
| | | CreateOrSelectRole = 3, |
| | | RoleLogin = 4, |
| | | Connected = 5, |
| | | DisConnected = 6, |
| | | } |
| | | |
| | | public struct CrossServerData |
| | | { |
| | | public string ip; |
| | | public int port; |
| | | public CrossServerState crossState; |
| | | |
| | | public CrossServerData(string ip, int port, byte state) |
| | | { |
| | | this.ip = ip; |
| | | this.port = port; |
| | | this.crossState = (CrossServerState)state; |
| | | } |
| | | } |
| | | |
| | | public enum CrossServerState |
| | | { |
| | | No = 0, |
| | | Yes = 1, |
| | | Error = 2, |
| | | } |
| | | |
| | | } |
| | | |
| | | public enum ServerType |
| | | { |
| | | Main = 1, |
| | | CrossSever = 2, |
| | | } |
copy from Utility/StringUtility.cs.meta
copy to Main/NetworkPackage/GameNetSystem.cs.meta
File was copied from Utility/StringUtility.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: c0960ed66238bdd49b70860dfee23488 |
| | | timeCreated: 1475005527 |
| | | guid: d15eb6a75fd16904c90f2b94e4b6a3b9 |
| | | timeCreated: 1490779004 |
| | | licenseType: Free |
| | | MonoImporter: |
| | | serializedVersion: 2 |
New file |
| | |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using UnityEngine; |
| | | using System; |
| | | using System.Text; |
| | | using System.IO; |
| | | |
| | | public class NetPkgCtl |
| | | { |
| | | private static List<NetPackage> packages = new List<NetPackage>(); //发送接收封包存储列表 |
| | | private static List<NetPackage> tempPackages = new List<NetPackage>();//暂停时缓存的封包列表 |
| | | public static bool stopRecieve = false; |
| | | |
| | | public static void RecordPackage(ServerType socketType, string bytes, NetPackagetType packType, string packageName, string fields, List<string> fieldDetails) |
| | | { |
| | | #if UNITY_EDITOR |
| | | var package = new NetPackage(); |
| | | package.socketType = socketType; |
| | | package.time = DateTime.Now.ToString("HH:mm:ss:fff"); |
| | | package.type = packType; |
| | | |
| | | if (string.IsNullOrEmpty(packageName)) |
| | | { |
| | | package.content = bytes.Replace(",", " "); |
| | | var byteStr = package.content.Split(' '); |
| | | if (byteStr.Length > 1) |
| | | { |
| | | package.name = StringUtility.Contact("H", byteStr[0], byteStr[1], "(未注册)"); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | package.content = bytes.Replace(",", " "); |
| | | package.name = packageName; |
| | | package.fields = fields; |
| | | package.fieldDetails = fieldDetails; |
| | | } |
| | | |
| | | if (!stopRecieve) |
| | | { |
| | | packages.Add(package); |
| | | } |
| | | else |
| | | { |
| | | tempPackages.Add(package); |
| | | } |
| | | #endif |
| | | } |
| | | |
| | | public static List<NetPackage> GetPackages() |
| | | { |
| | | return packages; |
| | | } |
| | | |
| | | public static List<NetPackage> GetTempPackages() |
| | | { |
| | | return tempPackages; |
| | | } |
| | | |
| | | public static void WriteAllNetLog(bool @details) |
| | | { |
| | | if (packages != null) |
| | | { |
| | | var count = 0; |
| | | var lines = new List<string>(); |
| | | for (int i = packages.Count - 1; i >= 0; i--) |
| | | { |
| | | if (count > 20000) |
| | | { |
| | | break; |
| | | } |
| | | |
| | | var package = packages[i]; |
| | | var line = string.Empty; |
| | | line = StringUtility.Contact(package.type == NetPackagetType.Client ? "【发送】\t" : "【接收】\t", package.time, ":", package.name, @details ? "\r\n" : "-->" + package.fields); |
| | | |
| | | if (@details && package.fieldDetails != null) |
| | | { |
| | | for (int j = 0; j < package.fieldDetails.Count; j++) |
| | | { |
| | | line = StringUtility.Contact(line, "\t\t\t", package.fieldDetails[j], "\r\n"); |
| | | } |
| | | } |
| | | |
| | | lines.Add(line); |
| | | count++; |
| | | } |
| | | |
| | | File.WriteAllLines(Application.dataPath + "/PackageLogs_" + (@details ? "details" : "abstract") + "_" + DateTime.Now.ToString("HH_mm_ss") + ".txt", lines.ToArray()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public class NetPackage |
| | | { |
| | | public ServerType socketType; |
| | | public bool show = false; |
| | | public string time; |
| | | public string serverTime; |
| | | public string content; |
| | | public string name; |
| | | public NetPackagetType type; |
| | | public string fields; |
| | | public List<string> fieldDetails; |
| | | } |
| | | |
| | | public enum NetPackagetType |
| | | { |
| | | Client = 1, |
| | | Server = 2, |
| | | All = 3, |
| | | } |
| | | |
copy from Utility/StringUtility.cs.meta
copy to Main/NetworkPackage/NetPkgCtl.cs.meta
File was copied from Utility/StringUtility.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: c0960ed66238bdd49b70860dfee23488 |
| | | timeCreated: 1475005527 |
| | | guid: e81970dd36cd37a4e99bb147804eee19 |
| | | timeCreated: 1505721949 |
| | | licenseType: Free |
| | | MonoImporter: |
| | | serializedVersion: 2 |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 2838f73e758458447bee2d084e64ae9d |
| | | folderAsset: yes |
| | | timeCreated: 1490778980 |
| | | licenseType: Free |
| | | DefaultImporter: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEngine; |
| | | using System; |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using System.Net; |
| | | using System.Net.Sockets; |
| | | using System.Threading; |
| | | |
| | | public class ClientSocket |
| | | { |
| | | GameNetEncode encoder = new GameNetEncode(); |
| | | Socket m_Socket; |
| | | public Socket socket { get { return m_Socket; } } |
| | | |
| | | private Thread m_packageThread; |
| | | private byte[] bufferBytes = new byte[4096]; // 4K,单包字节数组缓存 |
| | | private byte[] fragmentBytes; //留包后的内容 |
| | | private long getBytesTotal = 0; //发送的数据总量 |
| | | private long sendBytesTotal = 0; //发送的数据总量 |
| | | |
| | | public bool connected { get { return m_Socket == null ? false : m_Socket.Connected; } } |
| | | |
| | | ServerType socketType = ServerType.Main; |
| | | DateTime m_LastPackageTime; |
| | | public DateTime lastPackageTime { get { return m_LastPackageTime; } } |
| | | |
| | | bool isStopTreading = false; |
| | | |
| | | string ip; |
| | | int port; |
| | | Action<bool> onConnected = null; |
| | | |
| | | public ClientSocket(ServerType type) |
| | | { |
| | | this.socketType = type; |
| | | } |
| | | |
| | | public void Connect(string _ip, int _port, Action<bool> _onConnected) |
| | | { |
| | | try |
| | | { |
| | | ip = _ip; |
| | | port = _port; |
| | | onConnected = _onConnected; |
| | | //目前测试到异步两个问题 |
| | | // 1. BeginGetHostAddresses 不明情况下会很久才回调,导致触发超时 |
| | | // 2. 超时的情况下多次尝试登录后,会触发多次OnGetHostAddresses,导致登录异常 |
| | | //Dns.BeginGetHostAddresses(_ip, OnGetHostAddresses, null); |
| | | |
| | | IPAddress ipAddress; |
| | | #if UNITY_IPHONE |
| | | IPHostEntry ipAddresses = Dns.GetHostEntry(_ip); |
| | | ipAddress = ipAddresses.AddressList[0]; |
| | | |
| | | #else |
| | | IPAddress[] ipAddresses = Dns.GetHostAddresses(_ip); |
| | | ipAddress = ipAddresses[0]; |
| | | #endif |
| | | |
| | | |
| | | if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6) |
| | | { |
| | | Debug.Log("当前使用的网络: IPV6"); |
| | | m_Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); |
| | | } |
| | | else |
| | | { |
| | | Debug.Log("当前使用的网络: IPV4"); |
| | | m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); |
| | | } |
| | | |
| | | var ipEndPoint = new IPEndPoint(ipAddress, port); |
| | | if (ipEndPoint == null) |
| | | { |
| | | Debug.Log("IpEndPoint is null"); |
| | | } |
| | | |
| | | m_Socket.BeginConnect(ipEndPoint, new AsyncCallback(ConnectCallBack), null); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | Debug.LogError(e.Message); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | private void OnGetHostAddresses(IAsyncResult _result) |
| | | { |
| | | var ipAddresses = Dns.EndGetHostAddresses(_result); |
| | | |
| | | if (ipAddresses[0].AddressFamily == AddressFamily.InterNetworkV6) |
| | | { |
| | | Debug.Log("当前使用的网络: IPV6"); |
| | | m_Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); |
| | | } |
| | | else |
| | | { |
| | | Debug.Log("当前使用的网络: IPV4"); |
| | | m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); |
| | | } |
| | | |
| | | var ipEndPoint = new IPEndPoint(ipAddresses[0], port); |
| | | if (ipEndPoint == null) |
| | | { |
| | | Debug.Log("IpEndPoint is null"); |
| | | } |
| | | |
| | | m_Socket.BeginConnect(ipEndPoint, new AsyncCallback(ConnectCallBack), null); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 链接成功时的回调 |
| | | /// </summary> |
| | | /// <param name="_result"></param> |
| | | private void ConnectCallBack(IAsyncResult _result) |
| | | { |
| | | if (!_result.IsCompleted) |
| | | { |
| | | Debug.Log("链接超时!"); |
| | | CloseConnect(); |
| | | if (onConnected != null) |
| | | { |
| | | onConnected(false); |
| | | onConnected = null; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | try |
| | | { |
| | | if (m_Socket != null && m_Socket.Connected) |
| | | { |
| | | Debug.Log("确认的链接实现"); |
| | | OnConnectSuccess(); |
| | | } |
| | | else |
| | | { |
| | | if (m_Socket != null) |
| | | { |
| | | m_Socket.Disconnect(true); |
| | | } |
| | | } |
| | | } |
| | | catch (System.Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | finally |
| | | { |
| | | if (onConnected != null) |
| | | { |
| | | onConnected(m_Socket != null && m_Socket.Connected); |
| | | onConnected = null; |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | onConnected = null; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 关闭链接 |
| | | /// </summary> |
| | | public void CloseConnect() |
| | | { |
| | | Debug.Log("==== CloseConnect"); |
| | | try |
| | | { |
| | | isStopTreading = true; |
| | | if (m_packageThread != null) |
| | | { |
| | | m_packageThread.Abort(); |
| | | } |
| | | } |
| | | catch (System.Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | |
| | | try |
| | | { |
| | | if (m_Socket != null && m_Socket.Connected) |
| | | { |
| | | m_Socket.Shutdown(SocketShutdown.Both); |
| | | m_Socket.Close(); |
| | | } |
| | | } |
| | | catch (System.Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | |
| | | sendQueue.Clear(); |
| | | m_Socket = null; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 链接成功 |
| | | /// </summary> |
| | | private void OnConnectSuccess() |
| | | { |
| | | if (m_packageThread != null) |
| | | { |
| | | m_packageThread.Abort(); |
| | | m_packageThread = null; |
| | | } |
| | | |
| | | m_LastPackageTime = DateTime.Now; |
| | | m_packageThread = new Thread(new ThreadStart(ReceiveInfo)); // 启动线程接收信息 |
| | | m_packageThread.IsBackground = true; |
| | | m_packageThread.Start(); |
| | | isStopTreading = false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 接收信息 |
| | | /// </summary> |
| | | private void ReceiveInfo() |
| | | { |
| | | while (!isStopTreading) |
| | | { |
| | | try |
| | | { |
| | | var shutdown = false; |
| | | if (!m_Socket.Connected) |
| | | { |
| | | shutdown = true; |
| | | } |
| | | |
| | | if (!shutdown) |
| | | { |
| | | var dataLength = m_Socket.Receive(bufferBytes); |
| | | if (dataLength <= 0) |
| | | { |
| | | shutdown = true; |
| | | } |
| | | else |
| | | { |
| | | getBytesTotal += dataLength; |
| | | var bytes = new byte[dataLength]; |
| | | Array.Copy(bufferBytes, 0, bytes, 0, dataLength); |
| | | ReadInfo(bytes); |
| | | } |
| | | } |
| | | |
| | | if (shutdown) |
| | | { |
| | | isStopTreading = true; |
| | | m_Socket.Shutdown(SocketShutdown.Both); |
| | | m_Socket.Close(); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | Debug.Log(e); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | static byte[] vCmdBytes = new byte[2]; |
| | | /// <summary> |
| | | /// 阅读信息 |
| | | /// </summary> |
| | | /// <param name="vBytes"></param> |
| | | private void ReadInfo(byte[] vBytes) |
| | | { |
| | | try |
| | | { |
| | | byte[] fixBytes = vBytes; |
| | | // 如果存在留包,则并包 |
| | | if (fragmentBytes != null && fragmentBytes.Length > 0) |
| | | { |
| | | Array.Resize(ref fixBytes, vBytes.Length + fragmentBytes.Length); |
| | | Array.Copy(fragmentBytes, 0, fixBytes, 0, fragmentBytes.Length); |
| | | Array.Copy(vBytes, 0, fixBytes, fragmentBytes.Length, vBytes.Length); |
| | | } |
| | | |
| | | fragmentBytes = null; // 清理掉留包 |
| | | int vReadIndex = 0; // 初始指针 |
| | | byte[] vPackBytes; |
| | | int vLeavingLeng = 0; |
| | | int vBodyLeng = 0; |
| | | int vTotalLeng = fixBytes.Length; |
| | | GameNetPackBasic vNetpack; |
| | | |
| | | while (vReadIndex < vTotalLeng) |
| | | { |
| | | vLeavingLeng = vTotalLeng - vReadIndex; |
| | | if (vLeavingLeng < 6) // 未符合包的最低限度字节量, 留包 |
| | | { |
| | | fragmentBytes = new byte[vLeavingLeng]; |
| | | Array.Copy(fixBytes, vReadIndex, fragmentBytes, 0, vLeavingLeng); |
| | | break; |
| | | } |
| | | vBodyLeng = BitConverter.ToInt32(fixBytes, vReadIndex + 2); |
| | | if (vBodyLeng > vLeavingLeng - 6)// 未完整的包则留包 |
| | | { |
| | | fragmentBytes = new byte[vLeavingLeng]; |
| | | Array.Copy(fixBytes, vReadIndex, fragmentBytes, 0, vLeavingLeng); |
| | | break; |
| | | } |
| | | vPackBytes = new byte[vBodyLeng]; |
| | | Array.Copy(fixBytes, vReadIndex + 6, vPackBytes, 0, vBodyLeng); // 提取包的字节内容 |
| | | // 完整的包则读包 |
| | | |
| | | vPackBytes = encoder.BaseXorSub(vPackBytes); |
| | | Array.Copy(vPackBytes, 0, vCmdBytes, 0, 2); |
| | | var cmd = (ushort)((ushort)(vCmdBytes[0] << 8) + vCmdBytes[1]); |
| | | bool isRegist = false; // 未注册封包处理 |
| | | |
| | | // 处理主工程的封包 |
| | | if (PackageRegedit.Contain(cmd)) |
| | | { |
| | | vNetpack = PackageRegedit.TransPack(socketType, cmd, vPackBytes); |
| | | if (vNetpack != null) |
| | | { |
| | | if (Launch.Instance.EnableNetLog) |
| | | { |
| | | Debug.LogFormat("收包:{0}", vNetpack.GetType().Name); |
| | | } |
| | | m_LastPackageTime = DateTime.Now; |
| | | GameNetSystem.Instance.PushPackage(vNetpack, this.socketType); |
| | | isRegist = true; |
| | | } |
| | | } |
| | | |
| | | |
| | | vReadIndex += 6 + vBodyLeng; |
| | | |
| | | // 未注册封包处理 |
| | | if (!isRegist) |
| | | { |
| | | #if UNITY_EDITOR |
| | | PackageRegedit.TransPack(socketType, cmd, vPackBytes); |
| | | #endif |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.LogErrorFormat("收包异常:{0}", ex); |
| | | } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 发送信息 |
| | | /// </summary> |
| | | public void SendInfo(GameNetPackBasic protocol) |
| | | { |
| | | if (!connected) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | if (protocol == null) |
| | | { |
| | | Debug.LogError("要发的信息对象为空"); |
| | | return; |
| | | } |
| | | |
| | | if (Launch.Instance.EnableNetLog) |
| | | { |
| | | Debug.LogFormat("发包:{0}", protocol.GetType().Name); |
| | | } |
| | | |
| | | if (protocol.combineBytes == null) |
| | | { |
| | | protocol.WriteToBytes(); |
| | | } |
| | | protocol.CombineDatas(encoder); |
| | | #if UNITY_EDITOR |
| | | NetPkgCtl.RecordPackage(socketType, protocol.vInfoCont, NetPackagetType.Client, protocol.ToString(), FieldPrint.PrintFields(protocol), FieldPrint.PrintFieldsExpand(protocol, true)); |
| | | #endif |
| | | sendBytesTotal += protocol.combineBytes.Length; |
| | | SendBytes(protocol.combineBytes); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 发送信息 |
| | | /// </summary> |
| | | /// <param name="vBytes"></param> |
| | | public void SendInfo(byte[] vBytes) |
| | | { |
| | | if (!connected) |
| | | { |
| | | Debug.LogError("尚未与该后端链接!无法发送信息"); |
| | | return; |
| | | } |
| | | |
| | | if (vBytes == null || vBytes.Length < 2) |
| | | { |
| | | Debug.LogError("要发的信息数据为空或数据不足"); |
| | | return; |
| | | } |
| | | |
| | | vBytes = encoder.BaseXorAdd(vBytes); |
| | | byte[] vFrameHead = new byte[] { 255, 204 }; |
| | | byte[] vMsgBodyLength = BitConverter.GetBytes(vBytes.Length); |
| | | byte[] vTotal = new byte[vBytes.Length + 6]; |
| | | Array.Copy(vFrameHead, 0, vTotal, 0, vFrameHead.Length); |
| | | Array.Copy(vMsgBodyLength, 0, vTotal, 2, vMsgBodyLength.Length); |
| | | Array.Copy(vBytes, 0, vTotal, 6, vBytes.Length); |
| | | |
| | | SendBytes(vTotal); |
| | | } |
| | | |
| | | Queue<byte[]> sendQueue = new Queue<byte[]>(); |
| | | private void SendBytes(byte[] bytes) |
| | | { |
| | | try |
| | | { |
| | | if (sendQueue.Count > 0) |
| | | { |
| | | sendQueue.Enqueue(bytes); |
| | | } |
| | | else |
| | | { |
| | | m_Socket.BeginSend(bytes, 0, bytes.Length, SocketFlags.None, new AsyncCallback(SendInfoCallBack), m_Socket); |
| | | } |
| | | } |
| | | catch |
| | | { |
| | | Debug.LogError("网络数据包发送异常"); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 发送完成的回调 |
| | | /// </summary> |
| | | /// <param name="vAsyncSend"></param> |
| | | private void SendInfoCallBack(IAsyncResult vAsyncSend) |
| | | { |
| | | try |
| | | { |
| | | if (sendQueue.Count > 0) |
| | | { |
| | | var bytes = sendQueue.Dequeue(); |
| | | m_Socket.BeginSend(bytes, 0, bytes.Length, SocketFlags.None, new AsyncCallback(SendInfoCallBack), m_Socket); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Debug.Log(ex); |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: a21face58faa9ff48aaab18157a3a6d1 |
| | | MonoImporter: |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
New file |
| | |
| | | 脚本目录归类: |
| | | |
| | | ClientPack |
| | | 前端发给后端的协议包定义 |
| | | |
| | | ServerPack |
| | | 后端发给前端的协议包定义 |
| | | |
| | | Socket |
| | | Socket通迅逻辑 |
| | | |
| | | |
| | | 模块使用说明: |
| | | 请使用 GameNetSystem.Inst 引用通迅系统 |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 7d7ba81527e4e8b47aa40a31f36e028d |
| | | timeCreated: 1490779014 |
| | | licenseType: Free |
| | | TextScriptImporter: |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: da718520b160d8e42811e4591ee08143 |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | |
| | | |
| | | public partial class TeamBase |
| | | { |
| | | // 各种组队的养成系统等级 |
| | | |
| | | // 阵型内卡牌的羁绊增益 |
| | | |
| | | public void CalculateProperties(CardInfo cardInfo) |
| | | { |
| | | |
| | | } |
| | | |
| | | public void CalculatePower() |
| | | { |
| | | |
| | | } |
| | | } |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/Team/TeamBase.Properties.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: 7987ea50714808f4cb68eb80db70ab6b |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | |
| | | // 阵型基础 |
| | | |
| | | public partial class TeamBase |
| | | { |
| | | public TeamCard[] teamCards = new TeamCard[TeamConst.MaxTeamCardCount]; |
| | | |
| | | public int GetTeamCardCount() |
| | | { |
| | | int count = 0; |
| | | for (int i = 0; i < teamCards.Length; i++) |
| | | { |
| | | if (teamCards[i] != null) |
| | | { |
| | | count++; |
| | | } |
| | | } |
| | | |
| | | return count; |
| | | } |
| | | |
| | | public bool SwapTeamCard(int index1, int index2) |
| | | { |
| | | if (index1 < 0 || index1 >= teamCards.Length || index2 < 0 || index2 >= teamCards.Length) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | TeamCard temp = teamCards[index1]; |
| | | teamCards[index1] = teamCards[index2]; |
| | | teamCards[index2] = temp; |
| | | temp.cardIndex = index2; |
| | | teamCards[index1].cardIndex = index1; |
| | | |
| | | return true; |
| | | } |
| | | |
| | | public bool AddTeamCard(CardInfo cardInfo) |
| | | { |
| | | if (cardInfo == null) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | for (int i = 0; i < teamCards.Length; i++) |
| | | { |
| | | if (teamCards[i] == null) |
| | | { |
| | | teamCards[i] = new TeamCard(); |
| | | teamCards[i].cardInfo = cardInfo; |
| | | teamCards[i].cardIndex = i; |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | public bool RemoveTeamCard(int index) |
| | | { |
| | | if (index < 0 || index >= teamCards.Length) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | teamCards[index] = null; |
| | | return true; |
| | | } |
| | | |
| | | public bool IsFull() |
| | | { |
| | | return GetTeamCardCount() >= teamCards.Length; |
| | | } |
| | | |
| | | public bool IsEmpty() |
| | | { |
| | | return GetTeamCardCount() == 0; |
| | | } |
| | | } |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/Team/TeamBase.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: 201a5c1db01d2284f93b3099dc05bfe6 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | |
| | | |
| | | public class TeamCard |
| | | { |
| | | public CardInfo cardInfo; |
| | | public TeamBase teamBase; |
| | | public int cardIndex; |
| | | |
| | | public void MergeProperties() |
| | | { |
| | | if (cardInfo == null) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | } |
| | | } |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/Team/TeamCard.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: 87558c063506d4345a5d8b2e4496f85c |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | |
| | | |
| | | public class TeamConst |
| | | { |
| | | public const int MaxTeamCardCount = 6; |
| | | } |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/Team/TeamConst.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: 9333c652da8f9af4cb78b99ae93a4a8c |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: ed19de39701d6f34ca1ccc9485b759bd |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: e68e1dc0a519c794a9e1f8203e8f6b2a |
| | | folderAsset: yes |
| | | DefaultImporter: |
| | | externalObjects: {} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
New file |
| | |
| | | using UnityEngine; |
| | | using UnityEngine.UI; |
| | | |
| | | /// <summary> |
| | | /// 特效穿透阻挡器 |
| | | /// 将此脚本挂在特效游戏对象上,可以防止特效穿透UI界面 |
| | | /// </summary> |
| | | public class EffectPenetrationBlocker : MonoBehaviour |
| | | { |
| | | [Tooltip("是否在UI层级下自动调整排序顺序")] |
| | | public bool autoAdjustSorting = true; |
| | | |
| | | [Tooltip("特效渲染器,如果为空则自动获取")] |
| | | public Renderer[] effectRenderers; |
| | | |
| | | [Tooltip("特效粒子系统,如果为空则自动获取")] |
| | | public ParticleSystem[] particleSystems; |
| | | |
| | | [Tooltip("自定义排序顺序,仅在不自动调整时有效")] |
| | | public int customSortingOrder = 0; |
| | | |
| | | [Tooltip("自定义排序层,为空则使用默认UI层")] |
| | | public string customSortingLayer = "UI"; |
| | | |
| | | [Tooltip("特效所属的Canvas,如果为空则查找父级Canvas")] |
| | | public Canvas parentCanvas; |
| | | |
| | | [Tooltip("特效在Canvas中的排序偏移量")] |
| | | public int sortingOrderOffset = 1; |
| | | |
| | | private int canvasSortingOrder = 0; |
| | | |
| | | private void Awake() |
| | | { |
| | | // 如果没有指定渲染器,则自动获取 |
| | | if (effectRenderers == null || effectRenderers.Length == 0) |
| | | { |
| | | effectRenderers = GetComponentsInChildren<Renderer>(true); |
| | | } |
| | | |
| | | // 如果没有指定粒子系统,则自动获取 |
| | | if (particleSystems == null || particleSystems.Length == 0) |
| | | { |
| | | particleSystems = GetComponentsInChildren<ParticleSystem>(true); |
| | | } |
| | | |
| | | // 查找父级Canvas |
| | | if (parentCanvas == null) |
| | | { |
| | | parentCanvas = GetComponentInParent<Canvas>(); |
| | | } |
| | | |
| | | if (autoAdjustSorting) |
| | | { |
| | | UpdateSortingOrder(); |
| | | } |
| | | else |
| | | { |
| | | // 使用自定义排序 |
| | | ApplySortingSettings(customSortingOrder, customSortingLayer); |
| | | } |
| | | } |
| | | |
| | | private void OnEnable() |
| | | { |
| | | if (autoAdjustSorting) |
| | | { |
| | | UpdateSortingOrder(); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 更新排序顺序,确保特效显示在当前UI界面上方 |
| | | /// </summary> |
| | | public void UpdateSortingOrder() |
| | | { |
| | | if (!autoAdjustSorting) return; |
| | | |
| | | // 获取父级Canvas的排序顺序 |
| | | if (parentCanvas != null) |
| | | { |
| | | canvasSortingOrder = parentCanvas.sortingOrder; |
| | | } |
| | | else |
| | | { |
| | | // 如果没有找到父级Canvas,则使用默认值 |
| | | canvasSortingOrder = 0; |
| | | } |
| | | |
| | | // 将特效的排序顺序设置为Canvas排序顺序加上偏移量 |
| | | ApplySortingSettings(canvasSortingOrder + sortingOrderOffset, customSortingLayer); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 应用排序设置到所有渲染器和粒子系统 |
| | | /// </summary> |
| | | private void ApplySortingSettings(int sortingOrder, string sortingLayer) |
| | | { |
| | | // 应用到渲染器 |
| | | foreach (Renderer renderer in effectRenderers) |
| | | { |
| | | if (renderer != null) |
| | | { |
| | | renderer.sortingOrder = sortingOrder; |
| | | if (!string.IsNullOrEmpty(sortingLayer)) |
| | | { |
| | | renderer.sortingLayerName = sortingLayer; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 应用到粒子系统 |
| | | foreach (ParticleSystem ps in particleSystems) |
| | | { |
| | | if (ps != null) |
| | | { |
| | | ParticleSystemRenderer psRenderer = ps.GetComponent<ParticleSystemRenderer>(); |
| | | if (psRenderer != null) |
| | | { |
| | | psRenderer.sortingOrder = sortingOrder; |
| | | if (!string.IsNullOrEmpty(sortingLayer)) |
| | | { |
| | | psRenderer.sortingLayerName = sortingLayer; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 手动设置排序顺序 |
| | | /// </summary> |
| | | public void SetSortingOrder(int sortingOrder, string sortingLayer = null) |
| | | { |
| | | customSortingOrder = sortingOrder; |
| | | if (!string.IsNullOrEmpty(sortingLayer)) |
| | | { |
| | | customSortingLayer = sortingLayer; |
| | | } |
| | | |
| | | autoAdjustSorting = false; |
| | | ApplySortingSettings(customSortingOrder, customSortingLayer); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置父级Canvas |
| | | /// </summary> |
| | | public void SetParentCanvas(Canvas canvas) |
| | | { |
| | | parentCanvas = canvas; |
| | | if (autoAdjustSorting) |
| | | { |
| | | UpdateSortingOrder(); |
| | | } |
| | | } |
| | | } |
copy from Main/Character/CharacterBase.cs.meta
copy to Main/Tools/UI/EffectPenetrationBlocker.cs.meta
File was copied from Main/Character/CharacterBase.cs.meta |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 446cfdee2e270e2459fa4dbb2c33b152 |
| | | guid: 39babeee8ad50ae4f9dc961d33ec973a |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | |
| | | using UnityEngine;
|
| | | using DG.Tweening;
|
| | | using UnityEngine.UI; // DOTween 插件引用
|
| | | using Cysharp.Threading.Tasks;
|
| | |
|
| | | public enum UILayer
|
| | | {
|
| | |
| | | // 内部状态
|
| | | protected bool isActive = false;
|
| | | protected bool isAnimating = false;
|
| | | protected bool isClosing = false; // 新增:标记是否正在关闭
|
| | |
|
| | | // 组件引用
|
| | | protected Canvas canvas;
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | protected virtual void OnPreOpen()
|
| | | {
|
| | | // 子类可以重写此方法进行额外的预打开操作
|
| | | }
|
| | |
|
| | | protected virtual void OnPreClose()
|
| | | {
|
| | | // 子类可以重写此方法进行额外的预关闭操作
|
| | | }
|
| | |
|
| | | // 打开UI
|
| | | public virtual void HandleOpen()
|
| | | {
|
| | | OnPreOpen();
|
| | | // 如果正在播放动画,先停止
|
| | | StopCurrentAnimation();
|
| | |
|
| | | // 重置关闭标记
|
| | | isClosing = false;
|
| | | |
| | | gameObject.SetActive(true);
|
| | | isActive = true;
|
| | |
|
| | |
| | | PlayOpenAnimation();
|
| | |
|
| | | OnOpen();
|
| | |
|
| | | }
|
| | |
|
| | | // 关闭UI
|
| | | // 关闭UI - 修改后的方法
|
| | | public virtual void HandleClose()
|
| | | {
|
| | | // 如果已经在关闭过程中,直接返回
|
| | | if (isClosing) return;
|
| | | |
| | | OnPreClose();
|
| | | |
| | | // 如果正在播放动画,先停止
|
| | | StopCurrentAnimation();
|
| | |
|
| | | // 设置关闭标记
|
| | | isClosing = true;
|
| | | isActive = false;
|
| | | |
| | | // 禁用交互但保持可见
|
| | | if (canvasGroup != null)
|
| | | {
|
| | | canvasGroup.interactable = false;
|
| | | canvasGroup.blocksRaycasts = false;
|
| | | }
|
| | |
|
| | | // 根据动画类型播放关闭动画
|
| | | PlayCloseAnimation();
|
| | |
|
| | | // 调用关闭回调
|
| | | OnClose();
|
| | | gameObject.SetActive(false);
|
| | | isActive = false;
|
| | | |
| | | // 如果没有关闭动画,直接禁用游戏对象
|
| | | if (closeAnimationType == UIAnimationType.None)
|
| | | {
|
| | | CompleteClose();
|
| | | }
|
| | | // 否则在动画完成后禁用游戏对象(在PlayCloseAnimation中处理)
|
| | | }
|
| | |
|
| | | public void CloseWindow()
|
| | | // 完成关闭过程 - 新增方法
|
| | | protected virtual void CompleteClose()
|
| | | {
|
| | | gameObject.SetActive(false);
|
| | | isClosing = false;
|
| | | }
|
| | |
|
| | | public virtual void CloseWindow()
|
| | | {
|
| | | UIManager.Instance.CloseWindow(this);
|
| | | }
|
| | |
| | | Destroy(gameObject);
|
| | | }
|
| | |
|
| | | #endregion
|
| | | |
| | | #region 特效相关
|
| | | |
| | | /// <summary>
|
| | | /// 播放UI特效
|
| | | /// </summary>
|
| | | /// <param name="effectName">特效资源名称</param>
|
| | | /// <param name="parent">特效父节点,默认为当前UI</param>
|
| | | /// <param name="autoDestroy">是否自动销毁,默认为true</param>
|
| | | /// <param name="destroyDelay">自动销毁延迟时间,默认为5秒</param>
|
| | | /// <returns>特效游戏对象</returns>
|
| | | public async UniTask<GameObject> PlayUIEffect(string effectName, Transform parent = null, bool autoDestroy = true, float destroyDelay = 5f)
|
| | | {
|
| | | // 使用默认值
|
| | | if (parent == null) parent = transform;
|
| | | |
| | | // 加载特效资源
|
| | | GameObject effectPrefab = await ResManager.Instance.LoadAsset<GameObject>("UIEffect", effectName);
|
| | | if (effectPrefab == null)
|
| | | {
|
| | | Debug.LogError($"加载UI特效失败: {effectName}");
|
| | | return null;
|
| | | }
|
| | | |
| | | // 实例化特效
|
| | | GameObject effectObj = Instantiate(effectPrefab, parent);
|
| | | effectObj.name = $"Effect_{effectName}";
|
| | | |
| | | // 添加特效穿透阻挡器
|
| | | EffectPenetrationBlocker blocker = effectObj.AddComponent<EffectPenetrationBlocker>();
|
| | | blocker.parentCanvas = canvas;
|
| | | blocker.UpdateSortingOrder();
|
| | | |
| | | // 自动销毁
|
| | | if (autoDestroy)
|
| | | {
|
| | | Destroy(effectObj, destroyDelay);
|
| | | }
|
| | | |
| | | return effectObj;
|
| | | }
|
| | | |
| | | /// <summary>
|
| | | /// 在两个UI元素之间播放特效(按照sortingOrder的中间值)
|
| | | /// </summary>
|
| | | /// <param name="effectName">特效资源名称</param>
|
| | | /// <param name="frontElement">前景UI元素(Image或RawImage)</param>
|
| | | /// <param name="backElement">背景UI元素(Image或RawImage)</param>
|
| | | /// <param name="autoDestroy">是否自动销毁,默认为true</param>
|
| | | /// <param name="destroyDelay">自动销毁延迟时间,默认为5秒</param>
|
| | | /// <returns>特效游戏对象</returns>
|
| | | public async UniTask<GameObject> PlayEffectBetweenUIElements(string effectName, Graphic frontElement, Graphic backElement, bool autoDestroy = true, float destroyDelay = 5f)
|
| | | {
|
| | | if (frontElement == null || backElement == null)
|
| | | {
|
| | | Debug.LogError("前景或背景UI元素为空");
|
| | | return null;
|
| | | }
|
| | | |
| | | // 确保UI元素在当前UIBase的Canvas下
|
| | | if (frontElement.canvas != canvas || backElement.canvas != canvas)
|
| | | {
|
| | | Debug.LogError("UI元素不在当前UIBase的Canvas下");
|
| | | return null;
|
| | | }
|
| | | |
| | | // 加载特效资源
|
| | | GameObject effectPrefab = await ResManager.Instance.LoadAsset<GameObject>("UIEffect", effectName);
|
| | | if (effectPrefab == null)
|
| | | {
|
| | | Debug.LogError($"加载UI特效失败: {effectName}");
|
| | | return null;
|
| | | }
|
| | | |
| | | // 创建一个新的GameObject作为特效容器
|
| | | GameObject container = new GameObject($"EffectContainer_{effectName}");
|
| | | container.transform.SetParent(transform, false);
|
| | | |
| | | // 设置容器位置
|
| | | RectTransform containerRect = container.AddComponent<RectTransform>();
|
| | | containerRect.anchorMin = new Vector2(0.5f, 0.5f);
|
| | | containerRect.anchorMax = new Vector2(0.5f, 0.5f);
|
| | | containerRect.pivot = new Vector2(0.5f, 0.5f);
|
| | | containerRect.anchoredPosition = Vector2.zero;
|
| | | containerRect.sizeDelta = new Vector2(100, 100); // 默认大小,可以根据需要调整
|
| | | |
| | | // 获取前景和背景元素的siblingIndex
|
| | | int frontIndex = frontElement.transform.GetSiblingIndex();
|
| | | int backIndex = backElement.transform.GetSiblingIndex();
|
| | | |
| | | // 设置特效容器的siblingIndex在两者之间
|
| | | if (frontIndex > backIndex)
|
| | | {
|
| | | // 前景在背景之后,特效应该在中间
|
| | | container.transform.SetSiblingIndex((frontIndex + backIndex) / 2 + 1);
|
| | | }
|
| | | else
|
| | | {
|
| | | // 背景在前景之后,特效应该在中间
|
| | | container.transform.SetSiblingIndex((frontIndex + backIndex) / 2);
|
| | | }
|
| | | |
| | | // 实例化特效
|
| | | GameObject effectObj = Instantiate(effectPrefab, container.transform);
|
| | | effectObj.name = $"Effect_{effectName}";
|
| | | |
| | | // 添加特效穿透阻挡器
|
| | | EffectPenetrationBlocker blocker = effectObj.AddComponent<EffectPenetrationBlocker>();
|
| | | |
| | | // 直接设置特效渲染器的排序顺序
|
| | | Renderer[] renderers = effectObj.GetComponentsInChildren<Renderer>(true);
|
| | | foreach (Renderer renderer in renderers)
|
| | | {
|
| | | renderer.sortingOrder = canvas.sortingOrder;
|
| | | renderer.sortingLayerName = canvas.sortingLayerName;
|
| | | }
|
| | | |
| | | // 设置粒子系统渲染器的排序顺序
|
| | | ParticleSystem[] particleSystems = effectObj.GetComponentsInChildren<ParticleSystem>(true);
|
| | | foreach (ParticleSystem ps in particleSystems)
|
| | | {
|
| | | ParticleSystemRenderer psRenderer = ps.GetComponent<ParticleSystemRenderer>();
|
| | | if (psRenderer != null)
|
| | | {
|
| | | psRenderer.sortingOrder = canvas.sortingOrder;
|
| | | psRenderer.sortingLayerName = canvas.sortingLayerName;
|
| | | }
|
| | | }
|
| | | |
| | | // 自动销毁
|
| | | if (autoDestroy)
|
| | | {
|
| | | Destroy(container, destroyDelay);
|
| | | }
|
| | | |
| | | return effectObj;
|
| | | }
|
| | | #endregion
|
| | |
|
| | | #region 动画方法
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | // 播放关闭动画
|
| | | // 播放关闭动画 - 修改后的方法
|
| | | protected virtual void PlayCloseAnimation()
|
| | | {
|
| | | if (closeAnimationType == UIAnimationType.None)
|
| | | {
|
| | | // 无动画,直接禁用交互
|
| | | if (canvasGroup != null)
|
| | | {
|
| | | canvasGroup.alpha = 0f;
|
| | | canvasGroup.interactable = false;
|
| | | canvasGroup.blocksRaycasts = false;
|
| | | }
|
| | | // 无动画,直接返回,让HandleClose方法处理
|
| | | return;
|
| | | }
|
| | |
|
| | | isAnimating = true;
|
| | |
|
| | | // 禁用交互,但保持可见
|
| | | if (canvasGroup != null)
|
| | | {
|
| | | canvasGroup.interactable = false;
|
| | | canvasGroup.blocksRaycasts = false;
|
| | | }
|
| | |
|
| | | try
|
| | | {
|
| | |
| | | break;
|
| | | }
|
| | |
|
| | | // 动画完成后的回调
|
| | | // 动画完成后的回调 - 修改为调用CompleteClose
|
| | | currentAnimation.OnComplete(() =>
|
| | | {
|
| | | isAnimating = false;
|
| | |
|
| | | // 确保UI不可见且不可交互
|
| | | if (canvasGroup != null)
|
| | | |
| | | // 动画完成后,完成关闭过程
|
| | | if (isClosing)
|
| | | {
|
| | | canvasGroup.alpha = 0f;
|
| | | canvasGroup.interactable = false;
|
| | | canvasGroup.blocksRaycasts = false;
|
| | | CompleteClose();
|
| | | }
|
| | |
|
| | | // 延迟禁用GameObject,避免频繁的Enable/Disable操作
|
| | | // 如果需要立即释放资源,可以取消注释下面的代码
|
| | | // gameObject.SetActive(false);
|
| | | });
|
| | | }
|
| | | catch (System.Exception e)
|
| | | {
|
| | | Debug.LogError($"播放关闭动画时出错: {e.Message}");
|
| | |
|
| | | // 出错时确保UI不可见且不可交互
|
| | | if (canvasGroup != null)
|
| | | {
|
| | | canvasGroup.alpha = 0f;
|
| | | canvasGroup.interactable = false;
|
| | | canvasGroup.blocksRaycasts = false;
|
| | | }
|
| | | |
| | | // 出错时直接完成关闭
|
| | | isAnimating = false;
|
| | | CompleteClose();
|
| | | }
|
| | | }
|
| | |
|
| | |
| | |
|
| | | #region 初始化方法
|
| | |
|
| | |
|
| | | #region 缓存变量
|
| | | |
| | | // 缓存Transform查找结果
|
| | | private Dictionary<UILayer, Transform> layerTransformCache = new Dictionary<UILayer, Transform>();
|
| | | |
| | | // 缓存层级对应的基础排序顺序
|
| | | private Dictionary<UILayer, int> layerSortingOrderCache = new Dictionary<UILayer, int>();
|
| | | |
| | | #endregion
|
| | | |
| | | // 初始化缓存
|
| | | private void InitCache()
|
| | | {
|
| | | // 初始化层级Transform缓存
|
| | | layerTransformCache.Clear();
|
| | | layerTransformCache[UILayer.Static] = staticTrans;
|
| | | layerTransformCache[UILayer.Bottom] = bottomTrans;
|
| | | layerTransformCache[UILayer.Mid] = midTrans;
|
| | | layerTransformCache[UILayer.Top] = topTrans;
|
| | | layerTransformCache[UILayer.System] = systemTrans;
|
| | | |
| | | // 初始化层级排序顺序缓存
|
| | | layerSortingOrderCache.Clear();
|
| | | layerSortingOrderCache[UILayer.Static] = BASE_SORTING_ORDER;
|
| | | layerSortingOrderCache[UILayer.Bottom] = BASE_SORTING_ORDER * 10;
|
| | | layerSortingOrderCache[UILayer.Mid] = BASE_SORTING_ORDER * 100;
|
| | | layerSortingOrderCache[UILayer.Top] = BASE_SORTING_ORDER * 1000;
|
| | | layerSortingOrderCache[UILayer.System] = BASE_SORTING_ORDER * 10000;
|
| | | }
|
| | |
|
| | |
|
| | | // 初始化
|
| | | public void Init()
|
| | | {
|
| | |
| | | // 获取UI层级对应的基础排序顺序
|
| | | private int GetBaseSortingOrderForLayer(UILayer layer)
|
| | | {
|
| | | if (layerSortingOrderCache.TryGetValue(layer, out int order))
|
| | | return order;
|
| | | |
| | | // 如果缓存中没有,使用原来的方法计算并缓存结果
|
| | | int result;
|
| | | switch (layer)
|
| | | {
|
| | | case UILayer.Static:
|
| | | return BASE_SORTING_ORDER;
|
| | | result = BASE_SORTING_ORDER;
|
| | | break;
|
| | | case UILayer.Bottom:
|
| | | return BASE_SORTING_ORDER * 10;
|
| | | result = BASE_SORTING_ORDER * 10;
|
| | | break;
|
| | | case UILayer.Mid:
|
| | | return BASE_SORTING_ORDER * 100;
|
| | | result = BASE_SORTING_ORDER * 100;
|
| | | break;
|
| | | case UILayer.Top:
|
| | | return BASE_SORTING_ORDER * 1000;
|
| | | result = BASE_SORTING_ORDER * 1000;
|
| | | break;
|
| | | case UILayer.System:
|
| | | return BASE_SORTING_ORDER * 10000;
|
| | | result = BASE_SORTING_ORDER * 10000;
|
| | | break;
|
| | | default:
|
| | | return BASE_SORTING_ORDER * 10;
|
| | | result = BASE_SORTING_ORDER * 10;
|
| | | break;
|
| | | }
|
| | | |
| | | layerSortingOrderCache[layer] = result;
|
| | | return result;
|
| | | }
|
| | |
|
| | | // 获取层级对应的Transform
|
| | | private Transform GetTransForLayer(UILayer layer)
|
| | | {
|
| | | if (layerTransformCache.TryGetValue(layer, out Transform trans))
|
| | | return trans;
|
| | | |
| | | // 如果缓存中没有,使用原来的方法获取并缓存结果
|
| | | Transform result;
|
| | | switch (layer)
|
| | | {
|
| | | case UILayer.Static:
|
| | | return staticTrans;
|
| | | result = staticTrans;
|
| | | break;
|
| | | case UILayer.Bottom:
|
| | | return bottomTrans;
|
| | | result = bottomTrans;
|
| | | break;
|
| | | case UILayer.Mid:
|
| | | return midTrans;
|
| | | result = midTrans;
|
| | | break;
|
| | | case UILayer.Top:
|
| | | return topTrans;
|
| | | result = topTrans;
|
| | | break;
|
| | | case UILayer.System:
|
| | | return systemTrans;
|
| | | result = systemTrans;
|
| | | break;
|
| | | default:
|
| | | return bottomTrans;
|
| | | result = bottomTrans;
|
| | | break;
|
| | | }
|
| | | |
| | | layerTransformCache[layer] = result;
|
| | | return result;
|
| | | }
|
| | |
|
| | | // 获取UI实例,如果不存在则返回null
|