using CommonAI.Zone.Formula; using CommonAI.Zone.Helper; using CommonAI.Zone.Instance; using CommonAI.ZoneServer.JSGModule; using CommonLang; using CommonLang.Log; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using XmdsCommon.Plugin; using XmdsCommonServer.Plugin.XmdsSkillTemplate.Skills; using static CommonAI.ZoneClient.ClientStruct; using static XmdsCommonServer.Plugin.XmdsVirtual; namespace XmdsCommonServer.Plugin.JSGXmdsModule { public class JSGXmdsHackerModule { #if JSGProfile protected static readonly Logger log = LoggerFactory.GetLogger("JSGXmdsHackerModule"); /** 玩家击杀怪物 */ public static void OnPlayerKillMonster(InstancePlayer attacker, InstanceUnit monster) { //玩家属性打印 XmdsVirtual playerVir = (attacker.Virtual as XmdsVirtual); XmdsUnitProp CurProp = playerVir.MirrorProp; XmdsUnitProp oldProp = playerVir.GetOriginProp(); log.Info("ID:" + attacker.PlayerUUID + ", 所在场景:" + attacker.Parent.GetSceneID()); log.Info(", 当前血:" + attacker.CurrentHP + ",基础:" + oldProp.MaxAttack + ", " + oldProp.Defence + ", " + oldProp.MaxHP + ", 攻防血" + CurProp.MaxAttack + ", " + CurProp.Defence + ", " + CurProp.MaxHP + ", 妖:" + CurProp.monsterAtk + ", " + CurProp.monsterDef + ", 妖比:" + CurProp.monsterAtkPer + ", " + CurProp.monsterDefPer); log.Info("扩展属性1, 增减伤:" + CurProp.AllDmgAdd + ", " + CurProp.AllDmgReduce + ", 玩家增减伤:" + CurProp.PlayerDamageAdd + ", " + CurProp.PlayerDamageReduce + ", 神器伤:" + CurProp.ArtifactMainPer + ", boss伤害:" + CurProp.ToBossCritRate + ", " + CurProp.ToBossCritDamage + ", 杀意:" + CurProp.KillValuePer + ", 吸血" + CurProp.NormalAtkLeech + ", " + CurProp.ActiveAtkLeech + ", 怪伤害:" + CurProp.monsterDamageAdd + ", " + CurProp.monsterDamageReduce); log.Info("扩展属性1, 暴击率:" + CurProp.CritRate + ", 爆伤:" + CurProp.CritDamage + ", 回血:" + CurProp.MaxHPReborn + ", 韧性:" + CurProp.CtrlTimeReduce + ", CD缩减:" + CurProp.SkillCD + ", 治疗效果:" + CurProp.HealEffect + ", " + CurProp.HealedEffect + ", 移攻速:" + CurProp.MoveSpeed + ", " + CurProp.AttackSpeed + ", 技伤:" + CurProp.SkillDamageAdd); UnitBuffStatus[] buffStatus = attacker.GetCurrentBuffStatus(); if (buffStatus != null) { foreach (UnitBuffStatus buffItem in buffStatus) { log.Info("玩家buff:" + buffItem.ToString()); } } //检测基本属性是否有异常的,打印一下 float rate1 = oldProp.MaxAttack == 0 ? 1 : (float)(CurProp.MaxAttack) / oldProp.MaxAttack; float rate2 = oldProp.Defence == 0 ? 1 : CurProp.Defence / oldProp.Defence; float rate3 = oldProp.MaxHP == 0 ? 1 : CurProp.MaxHP / oldProp.MaxHP; if (rate1 > 1.2f || rate2 > 1.2f || rate3 > 1.2f) { HashMap playerProps = playerVir.GetChangePropMap(); foreach (PropChangeOperation chgProp in playerProps.Values) { log.Info("玩家变更属性:" + chgProp.ToString()); } } else { log.Info("无特别异常属性!"); } } /** 玩家伤害监测输出 */ public static void CheckAndPrintDamageLog(int damageBaseValue, XmdsVirtual attacker, XmdsVirtual hitter, AttackSource source, int damage, double DefCoef, float allDmgChgFinal, float monsterDmgChgFinal, float playerDmgChgFinal, float artifaceDmgChgFinal, float monsterAtkPer) { #if JSGProfile try { do { if (damageBaseValue > 50 && (damage <= 1 || damage > 20000)) { //如果基础防御或者伤害过高,就是测试号了 XmdsUnitProp attckOriginProp = attacker.GetOriginProp(); if (hitter.MirrorProp.Defence > 0 && attckOriginProp.Defence /hitter.MirrorProp.Defence > 10) { break; } int finalAttack = attacker.MirrorProp.GetFinalAttack(hitter.mUnit.IsMonster); if (finalAttack <= 0) { log.Warn("攻击者最大攻击属性异常:" + attacker.mUnit.Parent.GetSceneID() + ", " + finalAttack); } else if(damage * 1.0f / finalAttack < GetDamageWarnRate(source)) { break; } XmdsVirtual.FormatLog(LoggerLevel.WARNNING, "伤害异常 : {0}->{1}, ID:{2}-{3},{4}-{5},基础攻击:{6}", damageBaseValue, damage, attacker.mInfo.ID, attacker.mInfo.Name, hitter.mInfo.ID, hitter.mInfo.Name, finalAttack); XmdsVirtual.FormatLog(LoggerLevel.WARNNING, "--伤害信息 : {0}, {1}, {2}, {3}, {4}, {5}, {6}",(float)(1.0f- DefCoef), allDmgChgFinal, monsterDmgChgFinal, playerDmgChgFinal, artifaceDmgChgFinal, monsterAtkPer, JSGModule.GetAttackSourceDes(source)); //XmdsVirtual.FormatLog(LoggerLevel.ERROR, "3. 伤害异常受击防御 : {0},攻击穿透:{1},防御系数:{2},杀意信息:{3},{4}", // hitter.MirrorProp.Defence, attacker.MirrorProp.IgnoreDefensePer, GetDefenceAddition(hitter.GetStateLv()), // hitter.MirrorProp.KillValuePer, attacker.MirrorProp.KillValuePer); } } while (false); } catch (Exception e) { log.Error("JSGXmdsHackerModule PrintDamageInfo catch: " + e); } #endif } /** 玩家伤害监测输出 */ public static void PrintAttrErrorInfo(XmdsVirtual unit, UnitAttributeType Type, int value1, int value2) { #if JSGProfile try { bool needPrint = false; switch (Type) { case UnitAttributeType.Defence: needPrint = value1 > value2 * 4; break; case UnitAttributeType.MaxHP: needPrint = value1 > value2 * 1.5; break; default: needPrint = value1 > 10000; break; } if (needPrint) { string stackInfo = new StackTrace().ToString(); XmdsVirtual.FormatLog(LoggerLevel.ERROR, "属性异常异常 : UID:{0}, {1}, {2}, {3}, {4}", unit.mUnit.PlayerUUID, Type, value1, value2, stackInfo); } } catch (Exception e) { XmdsVirtual.FormatLog(LoggerLevel.ERROR, "PrintAttrErrorInfo异常:" + Type + ", " + value1 + ", " + value2 + ", " + e); } #endif } public static bool CheckAndPrintDmgWarn(string flag, XmdsVirtual attacker, XmdsVirtual hitter, float sourceDmg, float finalDmg, AttackSource source) { #if JSGProfile try { if (source == null || source.Attack == null || source.Attack.Properties.GetAttackID() == XmdsBattleSkill.DefaultSkillScriptID) { return false; } int checkValue = (source != null && source.Attack != null && source.Attack.Properties.GetAttackID() / 100 == 1104) ? attacker.mUnit.CurrentHP : attacker.MirrorProp.GetFinalAttack(hitter == null ? false : hitter.mUnit.IsMonster); if (finalDmg / sourceDmg > GetDamageWarnRate(source) || finalDmg / checkValue > 60) { log.Warn(flag + ", dmg: " + (int)finalDmg + ", src: " + (int)sourceDmg + ", attackerAtk: " + attacker.MirrorProp.MaxAttack + ", " + attacker.MirrorProp.MaxMonsterAttack + ", atkHP:" + attacker.mUnit.CurrentHP + ", AttackInfo:[" + attacker.mUnit.Info.ID + ", UUID: " + attacker.mUnit.PlayerUUID + "], hitterInfo:[" + hitter.mUnit.Info.ID + ", UUID: " + hitter.mUnit.PlayerUUID + ", " + JSGModule.GetAttackSourceDes(source)); return true; } } catch (Exception e) { log.Error("CheckAndPrintDmgWarn catch: ", e); } return false; #endif } /** 获得伤害倍率警告阈值 */ private static float GetDamageWarnRate(AttackSource source) { float dmgAddition = 0; float dmgBase = 3.0f; if(source != null) { if(source.FromSkillType == XmdsSkillType.cardSkill) { dmgBase = 5.0f; } else { dmgAddition = source.mDmgAddPer + 3; } } return dmgAddition + dmgBase; } /** 卡牌系统,输出卡牌数量异常日志 */ public static void CheckAndPrintCardSameErrorInfo(string tag, int cardSames, long ltime, AttackSource source) { #if JSGProfile if (cardSames <= 1) { log.Warn("触发卡牌数量异常:" + tag + ", " + ltime + ", " + JSGModule.GetAttackSourceDes(source)); } #endif } #endif } }