无限天堂

标题: 深度分析L1J的加速检测机制 [打印本页]

作者: 小茶犬    时间: 2008-8-11 15:31
标题: 深度分析L1J的加速检测机制
配置文件server.properties中的设定
------------------------------------------------------------
是否检测移动、攻击、施法速度
CheckMoveInterval = false
CheckAttackInterval = false
CheckSpellInterval = false
不正常速度累计次数满多少次后断线
InjusticeCount = 10
正常速度累计次数满多少次后清空不正常速度计数
JusticeCount = 4
检测系数,容许的检测偏差,105以上是放宽,100以下是严格
CheckStrictness = 102
------------------------------------------------------------


代码端AcceleratorChecker类的检测

L1J检测加速原理是根据客户端封包的发送间隔来做的。

系数经计算调整为0.97
private static final double CHECK_STRICTNESS = (Config.CHECK_STRICTNESS - 5) / 100D;

获取封包发送间隔并乘以系数0.97
long now = System.currentTimeMillis();
long interval = now - _actTimers.get(type);
interval *= CHECK_STRICTNESS;

根据动作类型获取正常间隔,动作类型有MOVE(移动), ATTACK(攻击), SPELL_DIR(有向魔法), SPELL_NODIR(无向魔法)
int rightInterval = getRightInterval(type);

计算,间隔大于0并且小于正常间隔,则非正常计数器+1,满10次后断线,记录日志并显示在控制台上,如果中间有累计4次间隔正常的,则非正常计数器清0
if (0 < interval && interval < rightInterval) {
    _injusticeCount++;
    _justiceCount = 0;
    if (_injusticeCount >= INJUSTICE_COUNT_LIMIT) {
        doDisconnect();
        return R_DISCONNECTED;
    }
    result = R_DETECTED;
} else if (interval >= rightInterval) {
    _justiceCount++;
        if (_justiceCount >= JUSTICE_COUNT_LIMIT) {
        _injusticeCount = 0;
        _justiceCount = 0;
    }
}

这个是L1J服务器端的检测,网络卡以至于速度变慢,封包发送的间隔是大于正常间隔的,所以属于正常范围的。

有一点疑问,也就是网络卡得不动的时候,天堂的客户端是否会把封包累积起来一下子发很多?这个从客户端的设计角度来看是不可能的,因为当客户端发送一个封包后只有等待服务器返回一个封包后才会发送下一个,就好比打了个怪物,服务器要返回你打中了怪物没,伤了多少血后,你才能发送下一个攻击封包。这也是为什么一个可以在5秒内打死的怪物,在卡了20秒后突然网络通了,怪物依旧还是要打5秒才能死,而不是被一连串的攻击封包而秒杀。


---------------------------------------------------------------------
无限的服务器是这样写的
        public boolean isFastMovable() {
                return (hasSkillEffect(L1SkillId.HOLY_WALK)
                                || hasSkillEffect(L1SkillId.MOVING_ACCELERATION)
                                || hasSkillEffect(L1SkillId.WIND_WALK));
        }

        public boolean isBrave() {
                return hasSkillEffect(L1SkillId.STATUS_BEGIN);
        }

        private int invisDelayCounter = 0;

        public boolean isInvisDelay() {
                return (invisDelayCounter > 0);
        }

        private Object _invisTimerMonitor = new Object();

        public void addInvisDelayCounter(int counter) {
                synchronized (_invisTimerMonitor) {
                        invisDelayCounter += counter;
                }
        }

        private static final long DELAY_INVIS = 3000L;

        public void beginInvisTimer() {
                addInvisDelayCounter(1);
                GeneralThreadPool.getInstance().pcSchedule(new L1PcInvisDelay(getId()),
                                DELAY_INVIS);
        }

        private long _oldMoveTimeInMillis = 0L;
        private int _moveInjustice = 0;

        public void checkMoveInterval() {
                long nowMoveTimeInMillis = System.currentTimeMillis();

                long moveInterval = nowMoveTimeInMillis - _oldMoveTimeInMillis;
                int speedStage = 0;
                if (hasSkillEffect(L1SkillId.STATUS_HASTE)
                                || hasSkillEffect(L1SkillId.HASTE) // GP、ヘイスト
                                || hasSkillEffect(L1SkillId.GREATER_HASTE)
                                || getMoveSpeed() == 1) { // グレーターヘイスト、ヘイスト状態
                        speedStage++;
                }
                if (hasSkillEffect(L1SkillId.STATUS_BEGIN)
                                || hasSkillEffect(L1SkillId.HOLY_WALK)
                                || hasSkillEffect(L1SkillId.MOVING_ACCELERATION)
                                || hasSkillEffect(L1SkillId.WIND_WALK)) {
                        speedStage++;
                }
                if (getTempCharGfx() == 3863 // ドワーフ
                                || getTempCharGfx() == 1037 // ジャイアントアント
                                || getTempCharGfx() == 95 // ジャイアントスパイダー
                                || getTempCharGfx() == 146 // ドレッドスパイダー
                                || getTempCharGfx() == 3631 // グリフォン
                                || getTempCharGfx() == 3632 // コカトリス
                                || getTempCharGfx() == 3888 // バフォメット
                                || getTempCharGfx() == 3905 // ベレス
                                || getTempCharGfx() == 4003 // ブラックナイト
                                || getTempCharGfx() == 4133 // ハイラクーン
                                || getTempCharGfx() == 2501) { // ジャックオーランタン
                        speedStage++;
                }
                int minMoveInterval = 0;
                if (speedStage == 0) { // 加速なし
                        minMoveInterval = Config.MINIMUM_MOVE_INTERVAL0;
                } else if (speedStage == 1) { // 1段階加速
                        minMoveInterval = Config.MINIMUM_MOVE_INTERVAL1;
                } else if (speedStage == 2) { // 2段階加速
                        minMoveInterval = Config.MINIMUM_MOVE_INTERVAL2;
                } else if (speedStage == 3) { // 3段階加速
                        minMoveInterval = Config.MINIMUM_MOVE_INTERVAL3;
                }
                if (minMoveInterval >= moveInterval) { // 移動要求の間隔が短すぎる
                        _moveInjustice++;
                        if (_moveInjustice >= Config.MOVE_INJUSTICE_COUNT) { // 連続で不正な移動要求間隔
                                _log.info("系統檢測出不正常移動速度," + getName() + "系統強制斷線。");
                                sendPackets(new S_Disconnect());
                                _moveInjustice = 0;
                        }
                } else { // 移動要求間隔が正常
                        _moveInjustice = 0;
                }

                _oldMoveTimeInMillis = nowMoveTimeInMillis;
        }

        private long _oldAttackTimeInMillis = 0L;
        private int _attackInjustice = 0;

        public int getAttackInjustice() {
                return _attackInjustice;
        }

        public void checkAttackInterval() {
                long nowAttackTimeInMillis = System.currentTimeMillis();
                long attckInterval = nowAttackTimeInMillis - _oldAttackTimeInMillis;
                if (Config.MINIMUM_ATTACK_INTERVAL >= attckInterval) { // 攻撃要求の間隔が短すぎる
                        _attackInjustice++;
                        if (_attackInjustice >= Config.ATTACK_INJUSTICE_COUNT) { // 連続で不正な攻撃要求間隔
                                _log.info("系統檢測出不正常攻擊速度," + getName() + "系統強制斷線。");
                                sendPackets(new S_Disconnect());
                                _attackInjustice = 0;
                        }
                } else { // 攻撃要求間隔が正常
                        _attackInjustice = 0;
                }
                _oldAttackTimeInMillis = nowAttackTimeInMillis;
        }

原理是一样的.不过排除了各个变身的攻击速度差异.也就是说.你在有些服务器变身南瓜人或拿加速的大巴武器可能会判定为加速,而这里不会

作者: touer001    时间: 2008-8-11 15:50
那可不可以这样理解,就算卡了,我按着血不放,等网络通了,一样能喝上血?而不是我被怪的攻击封包秒杀?
作者: staky    时间: 2008-8-11 15:51

果然是专门砌墙的程序员...
作者: 小茶犬    时间: 2008-8-11 16:12
不会,在服务期端,你依旧是在线的,怪物依旧在打你,只是,你没法发送喝水、攻击、移动之类的封包给服务器了,所以即使你按住喝水,还是要等网络通后一个一个计算的,而不是一下子会喝很多,但是怪物的攻击在服务器端的,所以是持续的在打你,卡久了,你就死了。
作者: 豪杰    时间: 2008-8-11 16:34
顶一个....内行..
这样一解释.很好.很透彻
作者: touer001    时间: 2008-8-11 16:38
恩,所以,我靠,保证服务器不卡,是楼上的首要责任~~~话说我已经被卡死过2次了
作者: 豪杰    时间: 2008-8-11 16:48
回楼上的  叫茶犬帮深度分晰一下..为什么会卡
作者: touer001    时间: 2008-8-11 17:12
不用他回答,我就能回答,一个是我客户端的数据传输问题,也就是常说的网络不稳定.
还有一个是因为服务器端数据流量超大造成数据堆积造成的卡,最主要原因也是因为有人开加速,封包发送量惊人,所以...加速的一定要封...

自然还有其他很多因素,但以上2个是最主要的.
我说的不是专业术语,但基本就是这个意思.
作者: 颓废三道    时间: 2008-8-11 18:10
谢谢小茶犬.不过.即使你发出来了.别人也未必看得懂.即使看懂了,也未必承认.so..这类问题,一般我不做什么解释.
作者: 颓废三道    时间: 2008-8-11 18:14
另外.这个应该是1008以下的检测机制
作者: staky    时间: 2008-8-11 21:57
原帖由 颓废三道 于 2008-8-11 18:10 发表
谢谢小茶犬.不过.即使你发出来了.别人也未必看得懂.即使看懂了,也未必承认.so..这类问题,一般我不做什么解释.


我终于理解你为啥 什么解释都不作了,今天小茶犬再群里跟你一个人吵了半天,什么证据都丢上去了,人家就是不承认...哎。。终于体会到了...
作者: 颓废三道    时间: 2008-8-12 07:45
楼上.
我从来没在群里和谁吵过什么.
也不知道你所指何事.
基本上我是不看群消息的.因为群实在太多了.实在看不过来,所以都设置了来消息不提示.然后关QQ时顺便关了.
不知道你指的是什么?
作者: staky    时间: 2008-8-12 09:24
原帖由 颓废三道 于 2008-8-12 07:45 发表
楼上.
我从来没在群里和谁吵过什么.
也不知道你所指何事.
基本上我是不看群消息的.因为群实在太多了.实在看不过来,所以都设置了来消息不提示.然后关QQ时顺便关了.
不知道你指的是什么?


只是体会一种心情...没有特指什么...哈哈不用太在意....

只是看到你那句话所想起来的..有些人自己错了,誓死不认账,即使证据摆在眼前,我的意思是你的心态不错.哈哈,没有别的意思..
作者: qq594qq    时间: 2008-8-13 00:14
虽然我看不懂,,,,但还是顶下
作者: 五月初五    时间: 2008-8-21 16:06
哎,真的佩服,可我看了半天看不懂是什么东东
作者: manman    时间: 2008-9-12 14:18
标题: 精华贴
如此精华不顶对不起毛主席
作者: 五月初五    时间: 2008-9-12 16:47
靠呀,说了不挖了,怎么又·························
作者: 去你的    时间: 2008-9-12 17:44
有时候卡的时候你一直按着3连射  等卡过来的时候  3连射就呼呼的射啊   这样会不会被算系统检测到不正常啊?
作者: 丑吖頭    时间: 2008-9-12 22:04


PP真的要抓起来打PP咯。。。
作者: kisa    时间: 2008-9-16 12:55
能不能翻译成汉语?




欢迎光临 无限天堂 (http://156.236.70.90/) Powered by Discuz! X2.5