开心网外挂开发之 三

经过前两篇文章,我们已经可以得到了我们的花园的基本信息了,并用xml反序列化来映射到相应的实体类中,有了花园信息,我就就要来研究其一些动作的实现了,比如说:浇水、除草、收获、偷盗等等功能具体是怎么来实现的, 首先还是打开fiddler2抓一下包看看

收获:

GET /!house/!garden/havest.php?
verify=22842320%5F1062%5F22842320%5F1245934796%5Fb2a24c5dfb54cbeb1498d95d42b820a4&seedid=0&farmnum=13&fuid=0&r=0%2E24021180626004934 HTTP/1.1
成功

<data><leftnum>2</leftnum><stealnum>0</stealnum>
<num>2</num><seedname>雪莲</seedname>
<fruitpic>http://img.kaixin001.com.cn//i2/house/garden/crop/xuelian.swf
</fruitpic><ret>succ</ret></data>
失败

<data><ret>fail</ret><reason>这块地没有东西可收获</reason></data>

偷盗:

GET /!house/!garden/havest.php?
verify=22842320%5F1062%5F22842320%5F1245934796%5Fb2a24c5dfb54cbeb1498d95d42b820a4
&seedid=0
&farmnum=14
&fuid=7033784
&r=0%2E7748989406973124 HTTP/1.1
成功

<data><anti>0</anti><leftnum>46</leftnum><stealnum>1</stealnum>
<num>1</num><seedname>牧草</seedname>
<fruitpic>http://img.kaixin001.com.cn//i2/house/garden/crop3/gouweiba.swf
</fruitpic><ret>succ</ret></data>
失败

<data><anti>0</anti><ret>fail</ret><reason>已偷过,做人要厚道</reason></data>

犁地:

GET /!house/!garden/plough.php?
verify=22842320%5F1062%5F22842320%5F1245934796%5Fb2a24c5dfb54cbeb1498d95d42b820a4
&seedid=0
&farmnum=13
&fuid=0
&r=0%2E09461198281496763 HTTP/1.1

成功
<data><ret>succ</ret></data>

失败
<data><ret>fail</ret><reason>已经犁过了,该播种了</reason></data>

播种:

GET /!house/!garden/farmseed.php?
verify=22842320%5F1062%5F22842320%5F1245934796%5Fb2a24c5dfb54cbeb1498d95d42b820a4
&seedid=63
&farmnum=13
&fuid=0
&r=0%2E42840757546946406 HTTP/1.1

成功
<data><ret>succ</ret></data>

失败
<data><ret>fail</ret><reason>这里不可以种喔</reason></data>

上面是几种基本状态请求的URL和返回操作成功还是失败的XML,我们可以按照上一扁的方法把返回的XML进行反序列化来让我们的程序得到这些状态。

我们先分析每个请求都向服务器发送了什么信息,其中的参数大部发好理解,我们就不说了,就一个verify和一个r不太清楚做什么用,我尝试着在浏览器里把这两个参数去掉然后访问,结果是,r有没有都无所谓,哪我们就不考虑它了,还有一个缺不可缺少,而且每次登录这个verify都会变化,我们哪里去取到这个值呢, 在分析了多个页面的原代码后,我们在http://www.kaixin001.com/!house/index.php页面的代码中找到了这串值,

开心网外挂开发之 三_第1张图片

先也别管他起什么作用了,把它抓出来才是正经。怎么抓出来,这个返回的可不是XML是一个乱七八糟的HTML,而且这串值还在一段js代码中,好在我们还有正则表达式这个武器,一切都迎刃而解了,在VS中敲出如下代码:

开心网外挂开发之 三_第2张图片

 

 

由于这个值在每一次登录以后不会改变,所以我的做好是在登录后就调用这个函数,并保存在一个类的公有变量中。

获得了这个verify的值后,我们就可以放心的写接下来的代码了,接下了就简单了,按上一篇的方法,写就可以了,先设计实体代码

 

 

[XmlRoot(ElementName  =   " data " )]
   
public   class  ReturnInfo
   {
       
public   string  ret;
       
public   string  reason;
       
public   int  anti;
   } 

大部分时候返回的XML就包含这些值,只有收获成功的时候才返回更多的信息,我们可以把这种情况做为Returninfo的一个子类来实现

 

 

Code
[XmlRoot(ElementName = "data")]
    
public class havestInfo:ReturnInfo
    {
        
public int leftnum { getset; }
        
public int stealnum { getset; }
        
public int num { getset; }
        
public string seedname { getset; } 

    } 

 我们的操作代码也很简单

 

 

Code
/// <summary>
/// 收获
/// </summary>
/// <param name="fuid"></param>
/// <param name="seedid"></param>
/// <param name="farmnum"></param>
/// <returns></returns>
public ReturnInfo HavestFarm(int fuid, int seedid, int farmnum)
{
            
string url = string.Format(havesturl,
                                    
this.g_verify,
                                    seedid.ToString(),
                                    farmnum.ToString(),
                                    fuid.ToString());
            
string str = this.myrequest.RequestByGet(url);
            
byte[] bytes = Encoding.GetEncoding("UTF-8").GetBytes(str);
            Stream s 
= new MemoryStream();
            s.Write(bytes, 
0, bytes.Length);
            s.Position 
= 0;
            XmlSerializer xmls 
= new XmlSerializer(typeof(ReturnInfo));
            ReturnInfo ret 
= (ReturnInfo)xmls.Deserialize(s);
            
return ret;

 

这个函数基本上符合了我们的要求,但是和我们昨天的代码对比一下,我们发现除了返回的类型不同,其它大部分的代码都重复了

7LM)WX$3(B0LN[)0B}YYA96

这些重复的代码,我们每一个操作都要写,太麻烦了,万一要修改哪不完玩了,重构一下,一开始我的办法是把这几行代码写到一个单独的函数中,但是我们很快发现,下面两句代码也只是稍有不同

X5}UL0I}NL[V}7`F`JRZE1S

 

{UB~Z@20D_J(DK@()5B%`$P

就这一点点的差别用普通函数来重构就麻烦了,但是好在C#2.0以后有了泛型这个好东东,看我七十二变

 

Code
public T Deserialize<T>(string url)
{
     
return Deserialize<T>(url, "");
}
public T Deserialize<T>(string url,string postdata)
{
     
//Stream s=StrtoStream(url);
     string str="";
     
if (postdata == "")
     {
         str 
= this.myrequest.RequestByGet(url);
     }
     
else
     {
         str 
= this.myrequest.RequestByPost(url, postdata);
     }
     
try
     { 

         
byte[] bytes = Encoding.GetEncoding("UTF-8").GetBytes(str);
         Stream s 
= new MemoryStream();
         s.Write(bytes, 
0, bytes.Length);
         s.Position 
= 0;
         XmlSerializer xmls 
= new XmlSerializer(typeof(T));
         T ret 
= (T)xmls.Deserialize(s);
         
return ret;
     }
     
catch (Exception ex)
     {
         Log.LogOut(ex.Message);
         
return default(T);
     }

 

接下来我们的代码就变成了这样了

 

Code
public GardenInfo GetGardenInfo(int uid)
       {
           
string url = string.Format("http://www.kaixin001.com/!house/!garden//getconf.php?verify={0}&fuid={1}",this.g_verify,uid); 


           GardenInfo curGardenInfo 
= this.Deserialize<GardenInfo>(url);

           
return curGardenInfo;
       } 

/// <summary>
     
/// 收获
     
/// </summary>
     
/// <param name="fuid"></param>
     
/// <param name="seedid"></param>
     
/// <param name="farmnum"></param>
     
/// <returns></returns>
     public ReturnInfo HavestFarm(int fuid, int seedid, int farmnum)
     {
         
string url = string.Format(havesturl,
                                 
this.g_verify,
                                 seedid.ToString(),
                                 farmnum.ToString(),
                                 fuid.ToString()); 

         
return (ReturnInfo)this.Deserialize<havestInfo>(url); 

     } 

     
/// <summary>
     
/// 浇水
     
/// </summary>
     
/// <param name="fuid"></param>
     
/// <param name="seedid"></param>
     
/// <param name="farmnum"></param>
     
/// <returns></returns>
     public ReturnInfo WaterFarm(int fuid, int seedid, int farmnum)
     {
         
string url = string.Format(waterurl,
                                 
this.g_verify,
                                 seedid.ToString(),
                                 fuid.ToString(),
                                 farmnum.ToString());
         
return this.Deserialize<ReturnInfo>(url);
     } 

     
/// <summary>
     
/// 买种子
     
/// </summary>
     
/// <param name="num">要卖的种子数量</param>
     
/// <param name="seedid">要卖的种子类型</param>
     
/// <returns></returns>
     public ReturnInfo BuySeed(int num, int seedid)
     {
         
string PostData = string.Format(buySeedPost,
                                 
this.g_verify,
                                 num.ToString(),
                                 seedid.ToString()); 

         
return Deserialize<ReturnInfo>(buySeedUrl, PostData);
     } 

     
/// <summary>
     
/// 除草
     
/// </summary>
     
/// <param name="fuid"></param>
     
/// <param name="seedid"></param>
     
/// <param name="farmnum"></param>
     
/// <returns></returns>
     public ReturnInfo KillGrass(int fuid, int seedid,int farmnum)
     {
         
string PostData = string.Format(KillGrassPost,
                                         
this.g_verify,
                                         seedid.ToString(),
                                         fuid.ToString(),
                                         farmnum.ToString());
         
return Deserialize<ReturnInfo>(KillGrassUrl, PostData);
     } 

 

是不是清爽了好多!

你可能感兴趣的:(开心网外挂开发之 三)