webqq2協議分析和qq聊天機器人簡單實現


轉之http://hfutxf.javaeye.com/blog/800866


通過webqq接口,可以實現發送qq消息接收qq消息等,這樣,想實現一個qq聊天機器人,就不是什麼難事情了了,下面開始一步步做。


1。首先調用http://ptlogin2.qq.com/check?appid=1003903&uin=qq號碼,來獲取該qq號碼驗證碼之類的信息。看返回結果決定是不是要輸入驗證碼登陸。
如果返回:ptui_checkVC('1','95ab7db15e5ab17f50f25d33598259e83ccc098c4af2f8a4');需要輸入驗證碼,這裏需要記住這個長字符串(獲取驗證碼圖片用)以及cookie
如果返回:ptui_checkVC('0','!MPG');不需要輸入驗證碼,驗證碼值用!MPG代替。可能爲其他字符串,但是以感嘆號開頭
如果需要輸入驗證碼:則調用
http://captcha.qq.com/getimage?aid=1003903&&uin=qq號碼&vc_type=95ab7db15e5ab17f50f25d33598259e83ccc098c4af2f8a4
獲取驗證碼圖片。。。
2。開始登陸,在登陸之前,需要將密碼加密,tx的加密方法很複雜,不過還好,弄到了他的js文件,然後通過java的ScriptEnginee來執行這個js來獲取加密後的字符串。。。
代碼:

Java代碼
  1. ScriptEngineManager m = new ScriptEngineManager();  
  2. ScriptEngine se = m.getEngineByName("javascript");  
  3. se.eval(new FileReader(new File("1.js")));  
  4. Object t = se.eval("md5(md5_3(/""+p+"/")+/""+code.toUpperCase()+"/");");  
  5. return t.toString();  
 

現在調用登陸接口,以獲得相關的cookie。注意Referer。這個一定得加上,否則不成功:Referer : http://web2-b.qq.com/proxy.html
http://ptlogin2.qq.com/login?u=qq號碼&p=密碼和驗證碼加密後的字符串&verifycode=驗 證碼&remember_uin=1&aid=1003903&u1=http%3A%2F %2Fweb2.qq.com%2Floginproxy.html%3Fstrong%

3Dtrue&h=1&ptredirect=0&ptlang=2052&from_ui=1&pttype=1&dumy=&fp=loginerroralert

登陸成功後,要記住返回的cookie值。
如其中ptwebqq,skey等。

3。這還沒有完成,還需要再次登錄,這個好像就是qq聊天接口登陸了(剛纔的登陸可以理解爲登陸qq網站),只有這次登陸,纔算真正登陸qq,這個時候,如果你qq已經登陸,會把你的qq踢下線,而且此次登陸纔算上線時間。
地址:http://web2-b.qq.com/channel/login,把一個數據結構post給它就夠了
r=%7B%22status%22%3A%22%22%2C%22ptwebqq%22%3A%22{1}%22%2C%22passwd_sig%22%3A%22%22%2C%22clientid%22%3A%22{2}%22%7D
其中{1}是ptwebqq,在第2步登陸後cookie返回的,{2}clientId,自己隨便定義一個數字吧。

如果成功:
會返回一個json數據結構:
{"retcode":0,"result":

{"uin":qq號 碼,"mode":"master","index":1055,"port":38138,"status":"online","vfwebqq":"f72a8722c988252aef4e0268f1d26a3d647f06f6ff353a5c6cdaaa49abb2fcdf0cee2d8d64373ac2","psessionid":"

8368046764001D636F6E6E7365727665725F77656271714031302E3133332E332E3234300000235100000B79026E040043F60C166D0000000A404746365677767041316D00000028F72A8722C988252AEF4E0268F1D26A3D647F06F6

FF353A5C6CDAAA49ABB2FCDF0CEE2D8D64373AC2"}}
記住其中的psessionid。後面在發送消息和獲取qq消息都需要這個參數。

4。發送一個qq消息給好友
地址:http://web2-b.qq.com/channel/send_msg
同樣是post:r={"to":qq號碼,"face":0,"content":"[/"23/",[/"font/",{/"name/":/"宋體/",/"size/":/"10/",/"style/":

[0,0,0],/"color/":/"000000

/"}]]","msg_id":7780001,"clientid":"15778909","psessionid":"8368046764001D636F6E6E7365727665725F77656271714031302E3133332E332E3234300000326F00000B71026E040043F60C166D0000000A4042725946

34574676716D00000028E7D8E44718236B0C17365E824FD3817ED2EF6C879FEE88D07EA92D030CEA72EE8E59309863128A3E"}
{"retcode":0,"result":"ok"}
需要把這個json UrlEncode一下再發送,否則會返回錯誤。

發送成功返回:{"retcode":0,"result":"ok"}

5。循環獲取消息接口:
通過這個接口你可以實時的不間斷的獲取最新的消息。
http://web2-b.qq.com/channel/poll?

clientid=15778909&psessionid=8368046764001D636F6E6E7365727665725F77656271714031302E3133332E332E3234300000326F00000B71026E040043F60C166D0000000A404272594634574676716D00000028E7D8E447182

36B0C17365E824FD3817ED2EF6C879FEE88D07EA92D030CEA72EE8E59309863128A3E&t=1288591644319

返回格式:
{"retcode":0,"result":[{"poll_type":"message","value": {"msg_id":9712,"from_uin":qq號碼,"to_uin":qq號 碼,"msg_id2":217523,"msg_type":9,"reply_ip":2887452740,"time":1288591740,"content":[["font",{"size":9,"color":"000000","style":

[0,0,0],"name":"/u5B8B/u4F53"}],"hello world"],"raw_content":"hello world"}}]}
其中的poll_type表示消息格式,message就是普通的qq消息,可以看到發送人,發送時間,以及消息的內容等。
此接口很特殊,在實現時,需要循環不間斷調用,如果沒有消息返回,該接口會一直等待到,有消息,讀取完後要立即再調用該接口。



6.其他接口
獲取頭像
http://face7.qun.qq.com/cgi/svr/face/getface?cache=0&type=1&fid=0&uin=號碼

獲取個人信息
http://web2-b.qq.com/api/get_single_info?tuin=qq號碼
獲取簽名
http://web2-b.qq.com/api/get_single_long_nick?tuin=qq號碼&t=1288751545148
獲取好友列表
http://web2-b.qq.com/api/get_user_friends
r    {"vfwebqq":"8f1383ba2239bb7295b100af215274aff1ee4be177b467cbc386fc53ff6606a8e5941aca61d0eb51"}
獲取在線的qq好友
http://web2-b.qq.com/channel/get_online_buddies?clientid=9547083&psessionid=8368046764001D636F6E6E7365727665725F77656271714031302E3133332E332E323430000062F000000B86026E040043F60C166D0000000A404F526B7558357668476D000000288F1383BA2239BB7295B100AF215274AFF1EE4BE177B467CBC386FC53FF6606A8E5941ACA61D0EB51&t=1288751548600
獲取最近聯繫人
http://web2-b.qq.com/api/get_recent_contact
r    {"vfwebqq":"8f1383ba2239bb7295b100af215274aff1ee4be177b467cbc386fc53ff6606a8e5941aca61d0eb51"}


等等。。。

7.附件這是本人通過java寫的一個實例客戶端,啓動後,處於接受qq消息狀態,當收到好友發來的消息時,回返回"然後呢?"。。。。
類似qq聊天機器人吧。。。
1.js是qq密碼的加密js文件。

。。

 

完整代碼:

Java代碼
  1. import java.awt.image.BufferedImage;  
  2. import java.io.BufferedReader;  
  3. import java.io.File;  
  4. import java.io.FileReader;  
  5. import java.io.InputStream;  
  6. import java.io.InputStreamReader;  
  7. import java.net.HttpURLConnection;  
  8. import java.net.URL;  
  9. import java.net.URLEncoder;  
  10. import java.util.Date;  
  11. import java.util.Random;  
  12. import java.util.regex.Matcher;  
  13. import java.util.regex.Pattern;  
  14.   
  15. import javax.imageio.ImageIO;  
  16. import javax.script.ScriptEngine;  
  17. import javax.script.ScriptEngineManager;  
  18.   
  19. import atg.taglib.json.util.JSONArray;  
  20. import atg.taglib.json.util.JSONException;  
  21. import atg.taglib.json.util.JSONObject;  
  22.   
  23.   
  24. public class QQClient {  
  25.   
  26.     private int qq = -1;  
  27.     private String pwd = null;  
  28.       
  29.     private int clientid = 66933334;//這個可以隨便寫  
  30.     private String psessionid = "";  
  31.       
  32.     private String ptwebqq;  
  33.     private String vfwebqq;  
  34.       
  35.     private String skey;  
  36.       
  37.     private String refer = "http://web2-b.qq.com/proxy.html";  
  38.       
  39.     private String cookie = "";  
  40.     //讀取消息線程  
  41.     private boolean isrun = false;  
  42.     private Thread poolThread =new PollThread();  
  43.     public Thread getPoolThread() {  
  44.         return poolThread;  
  45.     }  
  46.     /** 
  47.      * 記錄日誌 
  48.      */  
  49.     private void log(String msg){  
  50.         System.out.println(new Date().toLocaleString()+":"+msg);  
  51.     }  
  52.       
  53.       
  54.     public QQClient(int qq, String pwd) {   
  55.         this.qq = qq;  
  56.         this.pwd = pwd;  
  57.         try {  
  58.             boolean rs = checkAndLogin();  
  59.             if(rs){   
  60.                 isrun = true;  
  61.                 poolThread.start();//開始循環接收  
  62.                 log("啓動成功");  
  63.             }  
  64.         } catch (Exception e) {   
  65.             e.printStackTrace();  
  66.         }  
  67.     }  
  68.     /*****************華麗的分界線*****************/  
  69.     //測試  
  70.     public static void main(String[] args) throws Exception{  
  71.         QQClient q = new QQClient(qq號碼, "123");   
  72.         q.getPoolThread().join();  
  73.     }  
  74.       
  75.     /*****************華麗的分界線*****************/  
  76.     /** 
  77.      * 給toQQ發送一個msg消息,前提是toQQ是你的好友,要不然他收不到 
  78.      */  
  79.     public boolean sendMsg(int toQQ, String message){  
  80.         try {  
  81.             JSONObject json = new JSONObject();  
  82.             json.put("to", toQQ);//要發送的人  
  83.             json.put("face", 0);  
  84.               
  85.             JSONArray msg = new JSONArray();  
  86.             msg.add(message);  
  87.             JSONArray font = new JSONArray();  
  88.             font.add("font");  
  89.               
  90.             JSONObject font1 = new JSONObject().put("name", "宋體").put("size", "10");  
  91.               
  92.             JSONArray style = new JSONArray();  
  93.             style.add(0);  
  94.             style.add(0);  
  95.             style.add(0);         
  96.             font1.put("style", style);  
  97.             font1.put("color", "000000");  
  98.               
  99.             font.add(font1);       
  100.             msg.add(font);  
  101.               
  102.             json.put("content", msg.toString());  
  103.             json.put("msg_id", new Random().nextInt(10000000));  
  104.             json.put("clientid", clientid);  
  105.             json.put("psessionid", psessionid);//需要這個才能發送  
  106.             String sendMsgUrl = "http://web2-b.qq.com/channel/send_msg";  
  107.             String content = json.toString();  
  108.                
  109.             content = URLEncoder.encode(content);//他要需要編碼  
  110.             content ="r="+content;  
  111.             //發送  
  112.             String res = postUrl(sendMsgUrl, content);  
  113.             //不出意外,這是返回結果:{"retcode":0,"result":"ok"}  
  114.             JSONObject rh = new JSONObject(res);  
  115.             if("ok".equals(rh.getString("result"))){  
  116.                 return true;  
  117.             }   
  118.         } catch (JSONException e) {   
  119.             e.printStackTrace();  
  120.         }  
  121.           
  122.         return false;  
  123.     }  
  124.       
  125.     /** 
  126.      * 檢查並且登陸 
  127.      */  
  128.     private boolean checkAndLogin() throws Exception{  
  129.         if(qq == -1 || pwd == null)  
  130.             throw new IllegalArgumentException("qq和密碼不能爲空");  
  131.         String checkIdUrl = "http://ptlogin2.qq.com/check?appid=1003903&uin="+qq;  
  132.         String res = getUrl(checkIdUrl);  
  133.         //ptui_checkVC('0','!ZLE');返回這個就不需要獲取驗證碼了。驗證碼就是!ZLE   
  134.         //ptui_checkVC('1','95ab7db15e5ab17f50f25d33598259e83ccc098c4af2f8a4');這個長字符串就需要使用了  
  135.         Pattern p = Pattern. compile("//,//'([!//w]+)//'");  
  136.         Matcher m = p. matcher(res);  
  137.         String checkType = "";  
  138.         if(m.find()){  
  139.             checkType = m.group(1);   
  140.         }  
  141.         String check = "";   
  142.         if(!checkType.startsWith("!")){  
  143.             //需要輸入驗證碼  
  144.             String getCheckImageUrl = "http://captcha.qq.com/getimage?aid=1003903&uin="+qq+"&vc_type="+checkType;  
  145.             String file = readCheckImage(getCheckImageUrl);  
  146.             log("請打開"+file+",並且在這裏輸入其中的字符串,然後回車:");  
  147.             InputStreamReader ins = new InputStreamReader(System.in);  
  148.             BufferedReader br = new BufferedReader(ins);  
  149.             check = br.readLine();    
  150.         }else{  
  151.             //不需要輸入驗證碼  
  152.             check = checkType;  
  153.         }  
  154.           
  155.         //開始登陸  
  156.         String loginUrl = "http://ptlogin2.qq.com/login?u="+qq+"&" +  
  157.                 "p=" +mdP(pwd, check)+  
  158.                 "&verifycode="+check+"&remember_uin=1&aid=1003903" +  
  159.                 "&u1=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html%3Fstrong%3Dtrue" +  
  160.                 "&h=1&ptredirect=0&ptlang=2052&from_ui=1&pttype=1&dumy=&fp=loginerroralert";  
  161.         res = getUrl(loginUrl);  
  162. //      ptuiCB('0','0','http://web2.qq.com/loginproxy.html?strong=true','0','登錄成功!');  
  163. //      ptuiCB('4','0','','0','您輸入的驗證碼有誤,請重試。');  
  164.        
  165.         p = Pattern.compile("登錄成功!");//提取最後一個字符串,看看是不是 登錄成功!  
  166.         m = p. matcher(res);  
  167.         if(m.find()){  
  168.             log("登陸成功");   
  169.         }else{  
  170.             //登陸失敗  
  171.             log(checkType);  
  172.             return false;  
  173.         }  
  174.         //從cookie中提取ptwebqq,skey  
  175.         p = Pattern.compile("ptwebqq=(//w+);");  
  176.         m = p.matcher(cookie);  
  177.         if(m.find()){  
  178.             ptwebqq = m.group(1);  
  179.         }  
  180.         p = Pattern.compile("skey=(@//w+);");  
  181.         m = p.matcher(cookie);  
  182.         if(m.find()){  
  183.             skey = m.group(1);  
  184.         }  
  185.         log("ptwebqq="+ptwebqq+",skey="+skey);  
  186.           
  187.         //再次登陸,只有這次登陸,纔算真正登陸qq,這個時候,如果你qq已經登陸,會把你的qq踢下線,而且此次登陸纔算上線。  
  188.         String channelLoginUrl = "http://web2-b.qq.com/channel/login";  
  189.         String content = "{/"status/":/"/",/"ptwebqq/":/""+ptwebqq+"/",/"passwd_sig/":/"/",/"clientid/":/""+clientid+"/"}";  
  190.         content = URLEncoder.encode(content);//urlencode   
  191.         content = "r="+content;//post的數據  
  192.         res = postUrl(channelLoginUrl, content);//post  
  193.         //這次登陸基本上不會發生什麼問題  
  194.         //下面提取很重要的2個數據psessionid ,vwebqq,通用採用正則表達式,雖然結果是個json  
  195.         p = Pattern.compile("/"vfwebqq/":/"(//w+)/"");  
  196.         m = p.matcher(res);  
  197.         if(m.find()){  
  198.             vfwebqq = m.group(1);  
  199.         }  
  200.         p = Pattern.compile("/"psessionid/":/"(//w+)/"");  
  201.         m = p.matcher(res);  
  202.         if(m.find()){  
  203.             psessionid = m.group(1);  
  204.         }  
  205.         log("vwebqq="+vfwebqq+","+"psessionid="+psessionid);  
  206.         //到此,登陸就算完成了,後面可以調用發送qq信息等接口了         
  207.          return true;  
  208.     }  
  209.       
  210.   
  211.       
  212.       
  213.     /** 
  214.      * 調用tx的js來生成密鑰 
  215.      */  
  216.     public  String mdP(String p, String code){  
  217.         try {  
  218.             ScriptEngineManager m = new ScriptEngineManager();  
  219.             ScriptEngine se = m.getEngineByName("javascript");  
  220.             se.eval(new FileReader(new File("1.js")));  
  221.             Object t = se.eval("md5(md5_3(/""+p+"/")+/""+code.toUpperCase()+"/");");  
  222.             return t.toString();  
  223.         }catch (Exception e) {  
  224.             e.printStackTrace();  
  225.         }   
  226.         return null;  
  227.     }  
  228.     /** 
  229.      * POST一個url,contents是輸入的內容 
  230.      */  
  231.     private  String postUrl(String url, String contents){  
  232.         try{   
  233.             System.out.println("post>>>"+url);  
  234.                
  235.             URL serverUrl = new URL(url);  
  236.             HttpURLConnection conn = (HttpURLConnection) serverUrl.openConnection();   
  237.             conn.setRequestMethod("POST");//"POST" ,"GET"   
  238.              
  239.             if(refer != null){  
  240.                 conn.addRequestProperty("Referer", refer);  
  241.             }  
  242.             conn.addRequestProperty("Cookie", cookie);  
  243.             conn.addRequestProperty("Accept-Charset", "UTF-8;");//GB2312,  
  244.             conn.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8) Firefox/3.6.8");  
  245.             conn.setDoOutput(true);   
  246.             conn.connect();  
  247.               
  248.             conn.getOutputStream().write(contents.getBytes());  
  249.               
  250.             if(conn.getHeaderFields().get("Set-Cookie") != null){  
  251.                 for(String s:conn.getHeaderFields().get("Set-Cookie")){  
  252.                     cookie += s;  
  253.                 }  
  254.             }  
  255.               
  256.             InputStream ins =  conn.getInputStream();  
  257.               
  258.             String charset = "UTF-8";   
  259.             InputStreamReader inr = new InputStreamReader(ins, charset);  
  260.             BufferedReader bfr = new BufferedReader(inr);  
  261.              
  262.             String line = "";  
  263.             StringBuffer res = new StringBuffer();   
  264.             do{  
  265.                 res.append(line);  
  266.                 line = bfr.readLine();  
  267.                //System.out.println(line);  
  268.             }while(line != null);  
  269.             
  270.             System.out.println(">>>==="+res);  
  271.               
  272.             return res.toString();  
  273.         }catch(Exception e){  
  274.             e.printStackTrace();  
  275.             return null;  
  276.         }  
  277.     }  
  278.       
  279.       
  280.     /** 
  281.      * GET 一個url 
  282.      */  
  283.     private  String getUrl(String url){  
  284.         try{   
  285.             System.out.println("get>>>"+url);  
  286.                
  287.             URL serverUrl = new URL(url);  
  288.             HttpURLConnection conn = (HttpURLConnection) serverUrl.openConnection();   
  289.             conn.setRequestMethod("GET");//"POST" ,"GET"  
  290.            // conn.setDoOutput(true);   
  291.             if(refer != null){  
  292.                 conn.addRequestProperty("Referer", refer);  
  293.             }  
  294.             conn.addRequestProperty("Cookie", cookie);  
  295.             conn.addRequestProperty("Accept-Charset", "UTF-8;");//GB2312,  
  296.             conn.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8) Firefox/3.6.8");  
  297.             conn.connect();  
  298.              
  299.             if(conn.getHeaderFields().get("Set-Cookie") != null){  
  300.                 for(String s:conn.getHeaderFields().get("Set-Cookie")){  
  301.                     cookie += s;  
  302.                 }  
  303.             }  
  304.             InputStream ins =  conn.getInputStream();  
  305.               
  306.             String charset = "UTF-8";   
  307.             InputStreamReader inr = new InputStreamReader(ins, charset);  
  308.             BufferedReader bfr = new BufferedReader(inr);  
  309.              
  310.             String line = "";  
  311.             StringBuffer res = new StringBuffer();   
  312.             do{  
  313.                 res.append(line);  
  314.                 line = bfr.readLine();  
  315.                //System.out.println(line);  
  316.             }while(line != null);  
  317.             
  318.             System.out.println(">>>==="+res);  
  319.               
  320.             return res.toString();  
  321.         }catch(Exception e){  
  322.             e.printStackTrace();  
  323.             return null;  
  324.         }  
  325.     }  
  326.       
  327.     /** 
  328.      * 讀取驗證碼。返回驗證碼文件保存的路徑 
  329.      */  
  330.     private String readCheckImage(String url){  
  331.         try{   
  332.             System.out.println("get>>>"+url);  
  333.            
  334.             URL serverUrl = new URL(url);  
  335.             HttpURLConnection conn = (HttpURLConnection) serverUrl.openConnection();   
  336.             conn.setRequestMethod("GET");//"POST" ,"GET"   
  337.               
  338.             conn.addRequestProperty("Accept-Charset", "UTF-8;");//GB2312,  
  339.             conn.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8) Firefox/3.6.8");  
  340.             conn.connect();  
  341.             //返回的cookie  
  342.             if(conn.getHeaderFields().get("Set-Cookie") != null)  
  343.                 for(String s:conn.getHeaderFields().get("Set-Cookie")){  
  344.                     cookie += s;  
  345.                 }  
  346.               
  347.             InputStream ins =  conn.getInputStream();  
  348.               
  349.             BufferedImage bi = ImageIO.read(ins);  
  350.             File f =new File("qqimg.jpg");  
  351.             ImageIO.write(bi, "jpg", f);  
  352.               
  353.             return f.getAbsolutePath();  
  354.         }catch(Exception e){  
  355.             e.printStackTrace();   
  356.         }   
  357.         return null;  
  358.     }  
  359.       
  360.     /** 
  361.      * 當有qq消息是回調此函數 
  362.      */  
  363.     public void receiveMsg(String message, int fromQQ){  
  364.         log("qq:"+fromQQ+"說:"+message);  
  365.         //test  
  366.         sendMsg(fromQQ, "然後呢?");  
  367.     }  
  368.       
  369.     /** 
  370.      * 通過poll一直等待服務器迴應。比如收到消息啊,好友上線啊,申請好友啊之類的各類消息都會通過此接口返回,在獲得數據後,應該繼續poll獲取下個數據 
  371.      * http://web2-b.qq.com/channel/poll 
  372.      */  
  373.     class PollThread extends Thread{  
  374.           
  375.         private String pollUrl = "http://web2-b.qq.com/channel/poll";  
  376.         @Override  
  377.         public void run() {   
  378.             String url = pollUrl+ "?clientid="+clientid+"&psessionid="+psessionid;   
  379.               
  380.             try {  
  381.                 while(isrun){  
  382.                     //線程一直等待知道服務器有返回數據  
  383.                     String res = getUrl(url);  
  384.                       
  385.                     JSONObject retJ = new JSONObject(res);  
  386.                     if(retJ.getInt("retcode") == 0){  
  387.                         JSONArray result = retJ.getJSONArray("result");  
  388.                         String poll_type = result.getJSONObject(0).getString("poll_type");  
  389.                         if("message".equals(poll_type)){  
  390.                             //說明有人發qq消息給我,                            
  391.                             String raw_content = result.getJSONObject(0).getJSONObject("value").get("raw_content").toString();   
  392.                             int from_uin = result.getJSONObject(0).getJSONObject("value").getInt("from_uin");  
  393.                             log("收到來自:"+from_uin+":"+raw_content);  
  394.                             //通知客戶端收到了  
  395.                             receiveMsg(raw_content, from_uin);  
  396.                         }  
  397.                         //system_message 是系統消息  
  398.                     }  
  399.                 }  
  400.             } catch (JSONException e) {   
  401.                 e.printStackTrace();  
  402.             }  
  403.         }  
  404.           
  405.     }  
  406.   
  407.       
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章