论坛首页 Java企业应用论坛

山寨开心网停车外挂开发...

浏览 15607 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-01-10   最后修改:2009-02-25

前端时间玩了一下开心网,开心网里面有个争车位还蛮有意思的
车子少还好,车子多了就得一辆一辆的停,太麻烦了
于是就想弄个外挂看看,一搜索,一大堆外挂,用了一下还不错,
后来想了想,自己也写个几个小程序,也弄个山寨外挂看看,
于是GOOGLE,BAIDU,GO...



做一个Web游戏外挂需要的准备知识:
1) 需要有耐心
2) 熟悉HTML, JavaScript
3) 熟悉HTTP协议,特别是Cookie, URL的编码方式和POST, GET内容格式
4) 熟悉游戏本身,能抽象出最优的赚钱/升级的数学模型
5) 掌握一门语言,白菜萝卜都可以,我比较喜欢用Java和C#
6) 需要一些抓包的工具,比如HttpWatch



好了,来个例子,开心网争车位.语言:java,IDE:netbeans6.1

首先,我们看看一个正常用户玩的时候是怎么玩的。
1) 浏览器输入 www.kaixin001.com ,输入用户名,密码,点登陆
2) 登陆后选择左侧的“争车位”,进入到争车位
3) 看看自己的车哪些停车时间操作15分钟了,一一找个空的不免费的车位挪过去
4) 登出开心网,关闭浏览器



看看让程序怎么来实现1-4。
1) 登陆开心网
在HttpWatch的帮助下,我们知道登陆是把FORM提交到/login/login.php,POST内容是: 

     email         tbill@sina.com
     password 太复杂
     url             /


  
用apache的HttpClient可以方便的完成这个POST操作,然后得到服务器的返回,然后根据返回的内容里找一个关键字就可以判断这次登陆操作是否成功了。
以下是登陆代码片段

 CookieStore cookieStore = null;
        try {
            DefaultHttpClient httpclient = new DefaultHttpClient();
            //登陆
     //这里Constants是我自定义的一个常量类
            HttpPost httpost = new HttpPost(Constants.LOGINURL);
            //登陆的参数
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            //EMAIL
            nvps.add(new BasicNameValuePair(Constants.EMAIL, email));
            //密码
            nvps.add(new BasicNameValuePair(Constants.PASSWORD, password));
            //URL
            nvps.add(new BasicNameValuePair(Constants.URL, "/"));
            httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
            //执行登陆
            HttpResponse response = httpclient.execute(httpost);
            //获取HTTP响应头中的Set-Cookie
            Header header = response.getFirstHeader("Set-Cookie");
            HeaderElement[] elements = header.getElements();
            if (elements != null) {
                for (HeaderElement element : elements) {
                    if ("_user".equals(element.getName())) {
                        //  System.out.println(element.getValue());
                        if ("deleted".equals(element.getValue())) {
                            System.out.println("登陆失败");
                        } else {
                            System.out.println("登陆成功");
                            //获取cookies
                            cookieStore = httpclient.getCookieStore();
                        }
                        break;
                    }
                }
            }
     return cookieStore;

 

2) 登陆争车位
这次是一个GET操作,URL是/app/app.php?aid=1040。
需要说明一下的是,这里没有提供用户名密码,服务器怎么能知道是哪个用户呢?Cookie在这里就发挥了它的作用。
刚才在登陆的时候返回的CookieStore里存放的就是Cookies
然后所有的Http请求的Cookies都用它。
好了,取得这个页面以后,我们能得到很多信息:(这些信息是JSON格式)
a) 好友列表,每个好友的状态(在线/车位满)
b) 自己的车库信息,停了那些好友的哪些车,分别赚了多少钱
c) 自己的汽车信息,多少辆车,分别停在哪里,赚了多少钱
根据这些信息,我们可以得到一个停放的列表(车位不满的好友列表)


3) 挪车位
这个操作稍微复杂了一点点,具体的HTTP请求大家可以去分析一下
  a)获取好友车位信息,
    将有免费的车位的好友车位记录下来
   部分代码如下

DefaultHttpClient httpclient = new DefaultHttpClient(); 
            //登陆 
            HttpPost httpost = new HttpPost(FRIENDPARK); 
            //登陆的参数 
            List<NameValuePair> nvps = new ArrayList<NameValuePair>(); 
            //EMAIL 
            nvps.add(new BasicNameValuePair("_", null)); 
            //好友ID 
            nvps.add(new BasicNameValuePair("puid", puid)); 
            //验证字符串 
            nvps.add(new BasicNameValuePair("verify", verify)); 

            httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8)); 
            //设置COOKIES 
            HttpContext localContext = new BasicHttpContext(); 
            localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); 
            //进入好友车位 
            ResponseHandler<String> responseHandler = new BasicResponseHandler(); 
            //获取好友数据 
            String responseBody = httpclient.execute(httpost, responseHandler, localContext); 
            JSONObject friendJson = new JSONObject(responseBody); 
            // JSONArray parks = friendJson.getJSONArray("parking"); 
    //这里CommonFunction是我自定义的一个解析json数组的一个工具类 
            List list = CommonFunction.parseJsonArray(friendJson.getString("parking"), Parking.class); 

  
注:解析服务器返回的HTML我使用的是htmlparse

 

b) 如果是免费车位,停车,当然还要判断该车位上是否有汽车
在JavaScript里有代码:
v_park_free = (v_parkid >> 16) & 0xff;
      if (v_park_free)
      {
        v_mycar += '免费车位';
      }
      else
      {
        v_mycar += '私家车位';
      }
   用JAVA代码模拟一下

Integer parkid = Integer.parseInt(parking.getParkid()); 
   //flag=1是免费车位,flag=0不是免费车位 
   int flag = (parkid >> 16) & 0xff; 

停车: 
              DefaultHttpClient httpclient = new DefaultHttpClient(); 
                //停车 
                HttpPost httpost = new HttpPost(PARKINGURL); 
                //停车的参数 
                List<NameValuePair> nvps = new ArrayList<NameValuePair>(); 
                nvps.add(new BasicNameValuePair("_", null)); 
                nvps.add(new BasicNameValuePair("acc", parkEntity.getAcc())); 
                nvps.add(new BasicNameValuePair("carid", carid)); 
                nvps.add(new BasicNameValuePair("first_fee_parking", "0")); 
                nvps.add(new BasicNameValuePair("neighbor", neighbor)); 
                nvps.add(new BasicNameValuePair("park_uid", parkuid)); 
                nvps.add(new BasicNameValuePair("parkid", parking.getParkid())); 
                nvps.add(new BasicNameValuePair("verify", parkEntity.getVerify())); 

                httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8)); 

                //设置COOKIES 
                HttpContext localContext = new BasicHttpContext(); 
                localContext.setAttribute(ClientContext.COOKIE_STORE, parkEntity.getCookieStore()); 

                ResponseHandler<String> responseHandler = new BasicResponseHandler(); 
                //获取停车信息 
                String responseBody = httpclient.execute(httpost, responseHandler, localContext); 
                System.out.println(responseBody); 

                Map map = CommonFunction.parseJSON(responseBody); 
        //获取停车结果 
                res = Integer.parseInt((String) map.get("errno")); 

 

 

verify这个参数也需要从首页上提取
上面的acc要注意,这个acc是网页的一个动态js方法返回的数据
所以要获取这个动态的acc方法,然后执行该js获取结果
这是我的代码 

 

/** 
     * 调用自动生成的ACC方法 
     * @param script 
     * @return 
     */ 
    public static String invokeAccScript(String script) { 
        String acc = null; 
        try { 
            StringBuilder builder = new StringBuilder(); 
            BufferedReader reader1 = new BufferedReader(new StringReader(script)); 
            reader1.readLine(); 
            while ((acc = reader1.readLine()) != null) { 
                if (acc.startsWith("function notice()")) { 
                    break; 
                } else { 
                    builder.append(acc); 
                } 
            } 
            reader1.close(); 
            ScriptEngineManager m = new ScriptEngineManager(); 
            ScriptEngine engine = m.getEngineByName("javascript"); 
            if (engine != null) { 
                engine.eval(builder.toString()); 
                Invocable invocableEngine = (Invocable) engine; 
                //调用acc方法获取验证码 
                acc =  invocableEngine.invokeFunction("acc").toString(); 
            } 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
        return acc; 
    } 

 
4) 登出睡觉
GET URL: /login/logout.php



操作差不多就这些。
注:解析HTML使用的是Htmlparse
     模拟HTTP请求使用的是HttpClient
    解析json使用的是json.jar
    当然界面使用的是swing,SUN说jdk1.6的swing效率有了很大提升噢!

 

今天把源代码加上。。。

写得不好的地方请拍砖

   发表时间:2009-01-10  
开发出来了吗?
0 请登录后投票
   发表时间:2009-01-10  
java.lang.Object 写道
开发出来了吗?

开发出来了啊
不过就一个停车位的功能
哈哈!
0 请登录后投票
   发表时间:2009-02-01  
上传上来试用一下啊
0 请登录后投票
   发表时间:2009-02-02  
就是,分享一下咯……或者开源一下,大家一起完善开心网外挂~
0 请登录后投票
   发表时间:2009-02-17  
恩 思路基本一致 但是注意他的那个客户端的动态token的定位问题,记得去年做这个东西的时候kaixin001还是简单的post就可以了 然后又进化了一次 最后采用了这种客户端动态token的方式。
0 请登录后投票
   发表时间:2009-02-17  
Firefox + GreaseMonkey + UserScript 搞定webgame外挂
0 请登录后投票
   发表时间:2009-02-18  
very nice~
0 请登录后投票
   发表时间:2009-02-18  
现在好多基于flash,flex的webgame。开发这样的游戏外挂貌似要更加麻烦点吧。
0 请登录后投票
   发表时间:2009-02-20  
恩,学了不少东西
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics