📄 milyqq.java
字号:
/** MilyQQ - Simple Java QQ Client with a console interface** Copyright (C) 2006 spadger <echo.xjtu@gmail.com>** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileInputStream;import java.io.FileWriter;import java.io.InputStreamReader;import java.io.IOException;import java.io.File;import java.io.LineNumberReader;import java.net.InetSocketAddress;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.Map;import java.util.List;import java.util.Properties;import java.util.Scanner;import java.util.Collections;import java.util.Comparator;public class MilyQQ implements IQQListener { private QQClient client; private QQUser user; private String server; private boolean udp; private int qqno; private String qqpass; private boolean initHide; private boolean useProxy; private String proxyServer; private int proxyPort; private String proxyUser; private String proxyPass; private String proxyType; private int initStep; private final int stepCounter = 4; private int page; //用在一些需要页号的请求里面 private HashMap<Integer, QQFriend> friends; //全部好友 private HashMap<Integer, FriendRemark> remarks; //好友备注 private HashMap<Integer, ClusterInfo> clusters; //全部群信息.key为外部ID private HashMap<Integer, HashMap<Integer, QQFriend>> members;//全部群成员,Key为内部ID private HashMap<Integer, FriendStatus> friendStatus; //在线好友状态 private HashMap<Integer, Signature> signatures; //个性签名 private ArrayList<Integer> qqNumList; private ArrayList<Integer> index; //当前编号索引 private ArrayList<String> messages; //未显示的消息 private int chattingNo; //当前聊天的好友QQ号 private int chattingType; // 0 -一般用户, 1 - 群 private String chattingName; //当前聊天的好友Nick private BufferedWriter out; //聊天日志 private boolean isMask; //是否屏蔽消息 private boolean isSound; private boolean isLogin; private boolean isOnlineFinished; //是否取完在线好友 private boolean isSignatureOk; public static boolean isDebug; //总调试开关 private SoundPlayer soundPlayer; private final String commandArray[]={ "quit","exit","ls","list","lsa","listall","!","sound", "cd","mask", "state","status","help","info","send","sig","about","weather", "remark","lsg","update","login","logout","debug","listgroup" }; public MilyQQ() { //建立各种表 friends = new HashMap<Integer, QQFriend>(); remarks = new HashMap<Integer, FriendRemark>(); clusters = new HashMap<Integer, ClusterInfo>(); members=new HashMap<Integer,HashMap<Integer, QQFriend>>(); friendStatus = new HashMap<Integer,FriendStatus>(); signatures = new HashMap<Integer, Signature>(); qqNumList = new ArrayList<Integer>(); index = new ArrayList<Integer>(); messages = new ArrayList<String>(); soundPlayer = new SoundPlayer(); this.login(); //登录 try { out = new BufferedWriter(new FileWriter(qqno+".txt", true)); } catch (Exception ex) { System.out.println("不能打开聊天纪录,聊天纪录不能被保存..."); } System.out.print("Support & Bug report: spadger@bmy.xjtu <echo.xjtu@gmail.com>\n" +"欢迎使用MilyQQ. 键入'help'命令得到在线帮助\n"); BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); while (true) { chattingName=filterNewline(chattingName); System.out.print(chattingName + ">"); try { String input = stdin.readLine().trim(); processInput(input); for(String msg : messages) { System.out.print(msg); } messages.clear(); Thread.sleep(100); //等待操作完成 } catch (Exception ex) { if(isDebug) ex.printStackTrace(); } } } private void login() { Configure config = new Configure(); server = config.getServer(); udp = config.isUdp(); //这个函数总是返回UDP方式 qqno = config.getQQno(); qqpass = config.getQQpass(); initHide = config.isInitHide(); useProxy = config.isUseProxy(); proxyServer = config.getProxyServer(); proxyPort = config.getProxyPort(); proxyUser = config.getProxyUser(); proxyPass = config.getProxyPass(); proxyType = config.getProxyType(); isSound = config.isSound(); isDebug = config.isDebug(); initStep = 0; isMask = false; isLogin = true; isOnlineFinished = false; chattingNo = 0; chattingName = ""; chattingType = 0; user = new QQUser(qqno, qqpass); if (initHide) { user.setLoginMode(QQ.QQ_LOGIN_MODE_HIDDEN); user.setStatus(QQ.QQ_LOGIN_MODE_HIDDEN); System.out.println("隐身登陆..."); } else { user.setLoginMode(QQ.QQ_LOGIN_MODE_NORMAL); user.setStatus(QQ.QQ_LOGIN_MODE_NORMAL); System.out.println("正常登陆..."); } user.setUdp(udp); user.setShowFakeCam(true); //咱也有摄像头,嘿嘿 client = new QQClient(); client.addQQListener(this); client.setUser(user); client.setLoginServer(server); if (useProxy) { client.setProxy(new InetSocketAddress(proxyServer, proxyPort)); client.setProxyType(proxyType); if (!proxyUser.equals("")) { client.setProxyUsername(proxyUser); client.setProxyPassword(proxyPass); } } try { client.login(); } catch (Exception ex) { if(isDebug) ex.printStackTrace(); System.out.println("登录错误, 尝试使用login命令重新登录."); } System.out.println("正在连接服务器: "+server); } private void logout(){ chattingNo = 0; chattingName = ""; chattingType = 0; isLogin = false; friends.clear(); remarks.clear(); clusters.clear(); members.clear(); friendStatus.clear(); signatures.clear(); qqNumList.clear(); index.clear(); messages.clear(); try{ out.close();} catch (Exception ex) {} client.logout(); client.release(); System.out.println("注销当前登录账号,使用login命令重新登录."); } private boolean processInput(String input) { String inputArray[]=input.split("\\s",3); String cmd = inputArray[0].toLowerCase(); if (inputArray[0].equals("")) { //do nothing :) } else if (isMilyQQCommand(cmd)) { if (cmd.equals("exit") || cmd.equals("quit")) { client.logout(); System.out.print("拜拜!\n"); try{Thread.sleep(100); } catch (Exception ex) {} System.exit(0); } else if (cmd.equals("list")||cmd.equals("ls")) { if(inputArray.length==1) processCmdList(); else if(inputArray.length==2) processCmdList(inputArray[1]); else helpInfo("list"); } else if (cmd.equals("listall")||cmd.equals("lsa")) { if(inputArray.length==1) processCmdListAll(); else helpInfo("listall"); } else if (cmd.equals("listgroup")||cmd.equals("lsg")) { if(inputArray.length==1) processCmdListGroup(); else if(inputArray.length==2) processCmdListGroup(inputArray[1]); else helpInfo("listgroup"); } else if (cmd.equals("cd")) { if(inputArray.length==2) processCmdCd(inputArray[1]); else if(inputArray.length==1){ chattingNo=0; chattingName=""; }else helpInfo("cd"); } else if (cmd.equals("send")) { if(inputArray.length==3){ processCmdSend(inputArray[1],inputArray[2]); log(input); }else helpInfo("send"); } else if (cmd.equals("mask")) { isMask = !isMask; if(isMask) System.out.println("屏蔽消息模式. 按回车察看消息."); else System.out.println("不屏蔽消息模式."); } else if (cmd.equals("sound")) { if(inputArray.length==1){ isSound = !isSound; if(isSound) System.out.println("打开声音."); else System.out.println("关闭声音."); } else helpInfo("sound"); } else if (cmd.equals("debug")) { if(inputArray.length==1){ isDebug = !isDebug; if(isDebug) System.out.println("打开调试模式."); else System.out.println("关闭调试模式."); } else helpInfo("debug"); } else if (cmd.equals("state")||cmd.equals("status")) { if(inputArray.length==2) processCmdStatus(inputArray[1]); else helpInfo("status"); } else if (cmd.equals("info")) { if(inputArray.length==2) processCmdInfo(inputArray[1]); else helpInfo("info"); } else if (cmd.equals("update")) { if(inputArray.length==1) { client.sendPacket(new GetOnlineOpPacket(user)); requestSignature(); } else helpInfo("update"); } else if (cmd.equals("weather")) { if(inputArray.length==1) client.getWeather(); else helpInfo("weather"); } else if (cmd.equals("login") && isLogin == false) { if(inputArray.length==1) this.login(); else helpInfo("login"); } else if (cmd.equals("logout")) { if(inputArray.length==1 && isLogin == true) this.logout(); else helpInfo("logout"); } else if (cmd.equals("sig")) { if(inputArray.length==1) //requestSignature(); processCmdSig(); else helpInfo("sig"); } else if (cmd.equals("remark")) { if(inputArray.length==2) processCmdRemark(inputArray[1]); else helpInfo("remark"); } else if (cmd.equals("help")) { if(inputArray.length==2) helpInfo(inputArray[1]); else{ for(String str: commandArray) System.out.print(str+"\t"); System.out.print("\n以上为所有命令, 键入'help <命令>'得到更多信息.\n" +"更多细节请参考http://spadger.blog.com.cn\n"); } } else if(cmd.equals("about")){ System.out.print(" MilyQQ 2.0\n" +" Author: spadger@bmy.xjtu\n" +" Support & Bug report: <echo.xjtu@gmail.com>\n" +" My Blog: http://spadger.blog.com.cn\n" ); } else { System.out.println("未知命令! 键入'help' 得到在线帮助."); } } else if (input.startsWith("!")) { execExternalCMD(input.substring(1)); } else if (chattingNo != 0) { if(chattingType==0) client.sendIM(chattingNo, input); else if(chattingType==1) client.sendClusterIM(chattingNo, input); else{} log(input); } else{} return true; } private void helpInfo(String cmd){ if(cmd.equals("ls")||cmd.equals("list")){ System.out.print("ls/list [好友编号]: 无参数列出当前在线好友列表,有参数列出好友详细信息.\n"); } else if(cmd.equals("lsa")||cmd.equals("listall")){ System.out.print("lsa/listall: 列出所有好友.\n"); } else if(cmd.equals("lsg")||cmd.equals("listgroup")){ System.out.print("lsg/listgroup [群编号]: 无参数列出当前群,有参数列出群成员.\n"); } else if(cmd.equals("quit")||cmd.equals("exit")){ System.out.print("quit/exit: 退出MilyQQ.\n"); } else if(cmd.equals("mask")){ System.out.print("mask: 打开/关闭消息屏蔽模式.\n"); } else if(cmd.equals("sound")){ System.out.print("sound: 打开/关闭消息提示声音.\n"); } else if(cmd.equals("state")||cmd.equals("status")){ System.out.print("state/status <1|2|3|4|0>: 1-察看当前状态 2-在线 3-隐身 4-离开 0-离线\n"); } else if(cmd.equals("send")){ System.out.print("send <编号 | QQ号 | 群号> <消息>: 给好友或者群发送一个消息\n"); } else if(cmd.equals("cd")){ System.out.print("cd <编号 | QQ号 | 群号 | ..>: 和好友聊天或者进入一个群,键入'cd ..'离开.\n"); } else if(cmd.equals("!")){ System.out.print("!外部命令: 执行一个外部命令\n"); } else if(cmd.equals("update")){ System.out.print("update: 强制刷新在线好友列表\n"); } else if(cmd.equals("weather")){ System.out.print("weather: 得到本地的天气情况\n"); } else if(cmd.equals("sig")){ System.out.print("sig: 得到好友个性签名\n"); } else if(cmd.equals("login")){ System.out.print("login: 重新登录\n"); } else if(cmd.equals("debug")){ System.out.print("debug: 打开/关闭 调试模式.\n"); } else if(cmd.equals("logout")){ System.out.print("logout: 注销当前登录账号\n"); } else if(cmd.equals("remark")){ System.out.print("remark <编号 | QQ号>: 得到好友备注\n"); } else if(cmd.equals("info")){ System.out.print("info <编号 | QQ号>: 得到好友信息\n"); } else{ System.out.print("未知命令.\n"); } } private void processCmdList(){ int i=0; String gender = new String(); String status = new String(); String nick = new String(); String ip = new String(); if(!index.isEmpty()) index.clear(); System.out.print( "+编号+--QQ号码---+年龄+性别+状态+-------IP--------+------昵称(备注)-------+"); for (Map.Entry<Integer, QQFriend> entry : friends.entrySet()) { if(!friendStatus.containsKey(entry.getKey()))continue; if(friendStatus.get(entry.getKey()).status ==QQ.QQ_STATUS_OFFLINE)continue; index.add(entry.getKey()); gender = ((entry.getValue().gender==QQ.QQ_GENDER_GG) ?"GG":(entry.getValue().gender==QQ.QQ_GENDER_MM)?"MM":"??"); status = getCurrentStatus(friendStatus.get(entry.getKey()).status); ip = Util.getIpStringFromBytes( friendStatus.containsKey(entry.getKey()) ? friendStatus.get(entry.getKey()).ip : (new byte[4])); nick = filterNewline(entry.getValue().nick) + (remarks.containsKey(entry.getKey()) ? ("\t(" + remarks.get(entry.getKey()).name + ")") : ""); System.out.printf("\n%4d | %-10d|%3d | %s |%s| %-15s | %-16s", ++i, entry.getKey(), entry.getValue().age, gender, status, ip, nick); if(i%20==0) doPause(); } System.out.printf("\n+-------------------------------------------------------------------------+\n"); } private void processCmdList(String index_no){ if(!Util.isInt(index_no)){helpInfo("ls");return; } int id=Integer.parseInt(index_no);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -