【Android】声控注入点击事件实现系统级“吃鸡”辅助

这里我们从“吃鸡”说起。

绝·地·求·生 游戏的画面效果超级强悍,像我这样只玩掼蛋小游戏的三不青年(不抽烟,不喝酒,不玩网游)都被吸引到了

 

近年来掀起了一股“吃鸡”热潮,更衍生出了一种文化现象

(相关cosplay)

 

其手游版本也是相当火爆,直播平台上的观看人数都超级多,当然,不确定这里的数据是否有水分

 

 

一些周边产品也被带得风生水起

当然,也包括一些黑产,如外·挂,

(有些外·挂还是很有想象力的)

 

但是外·挂是“暴富宝典” ---- 《刑法》中挂了号的

(破坏计算机信息系统罪)

第二百八十六条 违反国家规定,对计算机信息系统功能进行删除、修改、增加、干扰,造成计算机信息系统不能正常运行,后果严重的,处五年以下有期徒刑或者拘役;后果特别严重的,处五年以上有期徒刑。

违反国家规定,对计算机信息系统中存储、处理或者传输的数据和应用程序进行删除、修改、增加的操作,后果严重的,依照前款的规定处罚。

故意制作、传播计算机病毒等破坏性程序,影响计算机系统正常运行,后果严重的,依照第一款的规定处罚。

作为有道德与社会责任感的我们,自然是不能去制作外·挂程序。

 

同时,一些物理辅助工具也火了起来,可以用来协助使用者进行多指操作,就像触控笔一样,方便了手指的触控操作,就加快了在游戏中的反应速度,关键时刻刚得过

(主要操作有 水平移动,视线旋转,射击,跳跃等,所以多指操作相对于2个拇指的操作要有优势)

作为Android Developer 我们完全可以在系统中通过注入点击事件来实现类似的功能。

声控设计

大吼一声,射击键就被点击起来,2个拇指进行其他的操作,这就实现了3指操作的效果。

主要步骤:

1.使用 AudioRecord实时获取外部声音的音量大小,达到设定的阈值时触发点击

                public RecordThread() { 

                super(); 

                bs = AudioRecord.getMinBufferSize(SAMPLE_RATE_IN_HZ, 

                        AudioFormat.CHANNEL_CONFIGURATION_MONO, 

                        AudioFormat.ENCODING_PCM_16BIT); 

                ar = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE_IN_HZ, 

                        AudioFormat.CHANNEL_CONFIGURATION_MONO, 

                        AudioFormat.ENCODING_PCM_16BIT, bs); 

            } 

          

            public void run() { 

                super.run(); 

                Log.d("getVoice", "run");

                ar.startRecording(); 

                        // ..... buffer 

                byte[] buffer = new byte[bs]; 

                isRun = true; 

                Log.d("getVoice", "buffer len=" + buffer.length);

                while (isRun) { 

                    int r = ar.read(buffer, 0, bs); 

                    int v = 0; 

                                // . buffer ............ 

                    for (int i = 0; i < buffer.length; i++) { 

                        // ...................... 

                        v += buffer[i] * buffer[i]; 

                    } 

                    // ................. sendMessage ...... Handler ......  

                    float soundLevel = v / (float) r;

                

 if (soundLevel > 3300){

                            sendLongPress(InputDevice.SOURCE_TOUCHSCREEN, 220, 330, 3000);

                        }

                } 

                ar.stop(); 

            } 

            public void pause() { 

                        // ....... Activity . onPause ...... Activity ........ 

                isRun = false; 

            } 

            public void start() { 

                        // ....... Activity . onResume ...... Activity .............. 

                if (!isRun) { 

                    super.start(); 

                } 

            } 

        }

2.模拟点击

//向inputManager发送一个touch事件,点击x=220, y=330的座标3000ms

sendLongPress(InputDevice.SOURCE_TOUCHSCREEN, 220, 330, 3000);

这里修改于 frameworks/base/cmds/input/src/com/android/commands/input/Input.java 里的处理

实现如下:

    private void injectMotionEvent(int inputSource, int action, long when, float x, float y, float pressure) {

        final float DEFAULT_SIZE = 1.0f;

        final int DEFAULT_META_STATE = 0;

        final float DEFAULT_PRECISION_X = 1.0f;

        final float DEFAULT_PRECISION_Y = 1.0f;

        final int DEFAULT_EDGE_FLAGS = 0;

        MotionEvent event = MotionEvent.obtain(when, when, action, x, y, pressure, DEFAULT_SIZE,

                DEFAULT_META_STATE, DEFAULT_PRECISION_X, DEFAULT_PRECISION_Y,

                getInputDeviceId(inputSource), DEFAULT_EDGE_FLAGS);

        event.setSource(inputSource);

        Log.i(TAG, "injectMotionEvent: " + event);

        InputManager.getInstance().injectInputEvent(event,

                InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);

    }

 

    private int getInputDeviceId(int inputSource) {

        final int DEFAULT_DEVICE_ID = 0;

        int[] devIds = InputDevice.getDeviceIds();

        for (int devId : devIds) {

            InputDevice inputDev = InputDevice.getDevice(devId);

            if (inputDev.supportsSource(inputSource)) {

                return devId;

            }

        }

        return DEFAULT_DEVICE_ID;

    }

 

    private void sendLongPress(int inputSource, float x, float y, int duration) {

        if (duration < 0) {

            duration = 300;

        }

        long now = SystemClock.uptimeMillis();

        injectMotionEvent(inputSource, MotionEvent.ACTION_DOWN, now, x, y, 1.0f);

        long startTime = now;

        long endTime = startTime + duration;

        while (now < endTime) {

//            injectMotionEvent(inputSource, MotionEvent.ACTION_MOVE, now, x, y, 1.0f);

            now = SystemClock.uptimeMillis();

        }

        injectMotionEvent(inputSource, MotionEvent.ACTION_UP, now, x, y, 0.0f);

    }


 

代言人

这样,戴上耳机,沉浸其中,大吼一声,多有气势

 

(这个试验场景是找了一个人机,瞄准好,咳嗽了一声,左边的射击键被点击)

好了,就到这里,有什么想法可以留言和我一起讨论。


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章