您现在的位置是:网站首页> C/C++
Qt写的游戏组队群聊系统
- C/C++
- 2025-12-14
- 2313人已阅读
摘要
Qt写的游戏组队群聊系统
善用AI辅助编程

Qt写的游戏组队群聊系统,可能是由于内容开始是网络地址(http://...)完整的英文词截取后不能换行造成 为避免代码造成手机端排版的混乱,可适当增加文字描述,将代码往后推移
#ifndef GETSERVERINFO_H#define GETSERVERINFO_H
#include <QObject>#include <QtNetwork/QTcpSocket>#include <QStringList>#include <httpget.h>//=====================================================================================================//WGM约战平台组队群聊系统.实现区域组队功能.获取玩家所在区域.玩家可以自己建立组队.队长踢人.解散等//此代码为核心网络通信模块.基于QT代码[完整源码在我的博客里面]//程序编程人员:Jason's.Alex QQ:531401335 //QT社区群:3855916//日期:2012/01/14//我会将WGM约战平台各个模块公开出来,整个平台用到了很多技术。我几乎花了半年的时间来开发这个平台,遗憾的我没有写开发文档,思路有点不清晰。虽然CS这个游戏落寞了。但是我们这些老菜鸟。希望能记起它说带来的美好//=====================================================================================================#define VERSION "1.2.1"
enum HostInfo//和主机通讯的消息{ HT_INFO,//群组信息 HT_MESSAGE,//消息 HT_KICK,//踢出 HT_ADVERTISING,//广告 HT_MEMBER,//成员 HT_DISSOLVE,//解散 HT_QUIT,//退出 HT_CREATE,//创建 HT_LOGIN,//登入 HT_TEAMANNOUNCEMENT=100//创建团队广播};
enum EnumChinaArea//中国各大地区分类{ ECA_ALL,//全部 ECA_SOUTHWEST,//西南 ECA_NORTHWEST,//西北 ECA_SOUTH,//华南 ECA_CENTRAL,//华中 ECA_EAST,//华东 ECA_NORTH,//华北 ECA_NORTHEAST,//东北
};
class GetServerInfo : public QObject{ Q_OBJECTpublic: explicit GetServerInfo(const QString &,const QString &,const QString &,QObject *parent = 0); void ConnectToHost();//连接主机
void SendMessage(const QString &);//发送消息 void SendKick(const QString &);//发送KICK void GetAdvertising();//获取广告 bool FilterArea(const QString local)const;//过滤区域
public slots: void SendQuit();//发送退出信息 void Login();//登入消息 void SendCreateTeam(const QString &,const QString &,const quint8);//发送创建消息 void SendRefreshMember();//发送刷新成员信息
signals: void EmitChangeAdvertising(const QPixmap &); void EmitMessage(const QString &); void EmitKick(); void EmitAnnouncement(const QString&); void EmitRefreshMember(const QStringList &); void EmitChangeWindowTitle(const QString &); void EmitUpdateVersion(const QStringList &);
private slots: void ReadMessgaeEvent();//读取消息时间 void ConnectFinish();//连接主机完成 void NetworkError(QAbstractSocket::SocketError);
private: void ReadMessage(QDataStream &in);//读取消息 void ReadKick(QDataStream &in);//读取KICK
void ReadAdvertising(QDataStream &in);//读取广告 void ReadMember(QDataStream &in); void ReadTeamInfo(QDataStream &in);//读取团队信息
void ReadLoginState(QDataStream &in);//读取登入状态
void SendServerDataType(HostInfo,const QStringList &list=QStringList());
const QStringList GetLocalAndCircuit(const QString &ip)const;//获取所在地区信息和线路信息
private: QTcpSocket *tcpClient; QString hostAddress; QString userName;//用户名字 QString teamID;//团队ID QString privilege;//权限 static QStringList filterChinaAreaList;//中国过滤区域列表 EnumChinaArea ChinaArea; //中国过滤的区域枚举值 HttpGet *webGet;//获取网页数据。进行分析取得ip地址信息 QString local,circuit;//地区和 线路};
#endif // GETSERVERINFO_H#include "getserverinfo.h"#include <QMessageBox>#include <QHostAddress>#include <QTimer>#include <QTime>#include <QNetworkInterface>#include <QDebug>
QStringList GetServerInfo::filterChinaAreaList=QStringList()<<QString::fromLocal8Bit("云南,贵州,四川,西藏") //西南 <<QString::fromLocal8Bit("新疆,陕西,宁夏,青海,甘肃") //西北 <<QString::fromLocal8Bit("广东,广西,海南,香港,澳门") //华南 <<QString::fromLocal8Bit("河南,湖北,湖南") //华中 <<QString::fromLocal8Bit("山东,江苏,安徽,浙江,台湾,福建,江西,上海") //华东 <<QString::fromLocal8Bit("河北,山西,内蒙古,北京,天津") //华北 <<QString::fromLocal8Bit("辽宁,吉林,黑龙江"); //东北
//=======================================================================================================================GetServerInfo::GetServerInfo(const QString &teamid,const QString &privi,const QString &name,QObject *parent) : QObject(parent){ teamID=teamid; privilege=privi; userName=name; hostAddress="113.140.83.67";
webGet=new HttpGet(this); webGet->setCodec("GB2312");
}
void GetServerInfo::ConnectToHost(){ tcpClient=new QTcpSocket(this);
tcpClient->connectToHost(hostAddress,8485,QIODevice::ReadWrite); connect(tcpClient,SIGNAL(connected()),SLOT(ConnectFinish())); connect(tcpClient,SIGNAL(readyRead()),SLOT(ReadMessgaeEvent())); connect(tcpClient,SIGNAL(error(QAbstractSocket::SocketError)),SLOT(NetworkError(QAbstractSocket::SocketError)));
}//=======================================================================================================================const QStringList GetServerInfo::GetLocalAndCircuit(const QString &ip)const//获取所在地区信息和线路信息{ QString content=webGet->get("http://www.ip138.com/ips138.asp?ip="+ip); uint leftIndex=content.indexOf("<li>"); uint rightIndex=content.indexOf("</li>"); content=content.mid(leftIndex+10,rightIndex-leftIndex-10); QStringList info(content.split(" ")); //0为所在地 1为线路 QStringList temp; temp.append(info[0]);
if(info.size()>1)//是否能捕获线路,防止程序出错 temp.append(info[1]); else temp.append(tr("unknown"));
return temp;}
bool GetServerInfo::FilterArea(const QString local)const//过滤区域{ if(ChinaArea==ECA_ALL) return true;
return filterChinaAreaList.at(ChinaArea-1).contains(local.left(2));}
//=======================================================================================================================void GetServerInfo::ConnectFinish(){ QStringList localAndCircuit=this->GetLocalAndCircuit(QNetworkInterface::allAddresses().first().toString()); local=localAndCircuit[0]; circuit=localAndCircuit[1];//获取线路信息}
void GetServerInfo::SendServerDataType(HostInfo hi, const QStringList &list){ QByteArray block; QDataStream out(&block,QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_7); out<<quint16(0)<<(quint8)hi; for (int i=0;i<list.size();++i) out<<list.at(i);
out.device()->seek(0); out<<quint16(block.size()-sizeof(quint16)); tcpClient->write(block);}
void GetServerInfo::GetAdvertising()//获取广告{ SendServerDataType(HT_ADVERTISING);}
void GetServerInfo::SendMessage(const QString &content)//发送消息{ QString s; if(privilege=="admin") s="<font color=red>"+content+"</font>"; else s="<font color=#484891>"+content+"</font>";
SendServerDataType(HT_MESSAGE,QStringList()<<teamID<<userName+"("+local+circuit+")"<<s);}
void GetServerInfo::SendKick(const QString &id)//kick{ SendServerDataType(HT_KICK,QStringList()<<teamID<<id);}
void GetServerInfo::SendRefreshMember()//发送刷新成员信息{ SendServerDataType(HT_MEMBER,QStringList()<<teamID);}
void GetServerInfo::SendQuit()//发送退出信息{ if(privilege=="admin")//如果是管理员就解散该群 { SendServerDataType(HT_DISSOLVE,QStringList()<<teamID); } else { SendServerDataType(HT_QUIT,QStringList()<<teamID<<userName); } tcpClient->waitForBytesWritten(200);//保证关闭时能够准确发送退出信息}
void GetServerInfo::SendCreateTeam(const QString &teamFlag,const QString &content,const quint8 area)//发送创建群{ SendServerDataType(HT_CREATE,QStringList()<<teamFlag<<content<<userName<<QString::number(area));}
void GetServerInfo::Login()//登入{ SendServerDataType(HT_LOGIN,QStringList()<<teamID<<userName);}
//=====================================================================================void GetServerInfo::ReadMessgaeEvent(){ QDataStream in(tcpClient); in.setVersion(QDataStream::Qt_4_7); static quint32 size=0; quint8 type; if(size==0) in>>size;
qDebug()<<tcpClient->bytesAvailable(); if(size>tcpClient->bytesAvailable()) return;
size=0;
in>>type;
switch(type) {
case HT_INFO://读取团队信息 ReadTeamInfo(in); break;
case HT_MESSAGE://消息 ReadMessage(in); break;
case HT_KICK://KICK ReadKick(in); break;
case HT_ADVERTISING://广告 ReadAdvertising(in); break; case HT_MEMBER://读取成员 ReadMember(in); break;
case HT_LOGIN: ReadLoginState(in); break;
case HT_DISSOLVE:// 解散 QMessageBox::information(0,tr("SystemInfo!"),tr("This team Group is Dissolve!")); emit EmitKick(); break;
}
tcpClient->flush();}
void GetServerInfo::ReadTeamInfo(QDataStream &in)//读取团队信息{ QString announcement,teamFlag,area,version; in>>announcement>>teamFlag>>teamID>>area>>version;
emit EmitAnnouncement("<font color=blue>"+announcement+"</font>");
emit EmitChangeWindowTitle(tr(" TeamFlag:")+teamFlag); emit EmitChangeWindowTitle(tr(" (ID:%1)").arg(teamID));
ChinaArea=(EnumChinaArea)area.toInt();
if(!FilterArea(local)&&privilege!="admin")//过滤区域 { QMessageBox::information(0,tr("Area failed!"),tr("You Area cannot access!")); emit EmitKick(); }
QStringList list=version.split(",");//版本更新 if(list[0]!=VERSION) { QStringList data; for(int i=1;i<list.size();++i) data<<list.at(i); emit EmitUpdateVersion(data); }
this->SendRefreshMember();//接受完成后刷新成员}
void GetServerInfo::ReadAdvertising(QDataStream &in)//读取广告{ QPixmap image; in>>image; emit EmitChangeAdvertising(image);}
void GetServerInfo::ReadKick(QDataStream &in)//读取K掉的用户{ QString s; in>>s; if(s==userName&&privilege!="admin") { QMessageBox::information(0,tr("kick!"),tr("You have been kicked by administrator!")); emit EmitKick(); }}
void GetServerInfo::ReadMessage(QDataStream &in)//读取信息{ QString ID,content; in>>ID>>content; emit EmitMessage(tr("<font color=blue>%1</font><br> %2<br>").arg(ID+QTime::currentTime().toString(" hh:mm:ss")).arg(content));}
void GetServerInfo::ReadMember(QDataStream &in)//读取成员{ QString id; QStringList list; while(!in.atEnd()) { in>>id; if(!id.isEmpty()) list<<id; }
emit EmitRefreshMember(list);}
void GetServerInfo::ReadLoginState(QDataStream &in)//读取登入状态{ bool state; in>>state; if(!state)//登入失败提示 { QMessageBox::warning(0,tr("Team Dissolve"),tr("Team group is dissolve! \n Cannot Alredy Login is same ream Group!")); emit EmitKick(); }}
//=================================================================================================================
void GetServerInfo::NetworkError(QAbstractSocket::SocketError error){ if(hostAddress!="jasonsalex.gicp.net")//连接失败使用备用地址 { delete tcpClient; hostAddress="jasonsalex.gicp.net"; this->ConnectToHost(); }else {
QMessageBox::warning(0,tr("network error"),tcpClient->errorString()); emit EmitKick(); }}#ifndef MAINWINDOW_H#define MAINWINDOW_H
#include <QMainWindow>#include <getserverinfo.h>#include <QStandardItemModel>#include <createdialog.h>#include <CustomGUI.h>#include <QTimer>#include <QProcess>//=====================================================================================================//WGM约战平台组队群聊系统.实现区域组队功能.获取玩家所在区域.玩家可以自己建立组队.队长踢人.解散等//主界面的实现.基于QT代码//程序编程人员:Jason's.Alex QQ:531401335 //QT社区群:3855916//日期:2012/01/14//我会将WGM约战平台各个模块公开出来,整个平台用到了很多技术。我几乎花了半年的时间来开发这个平台,遗憾的我没有写开发文档,思路有点不清晰。虽然CS这个游戏落寞了。但是我们这些老菜鸟。希望能记起它说带来的美好//=====================================================================================================namespace Ui { class MainWindow;}
class MainWindow : public QMainWindow{ Q_OBJECT
public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); void CreateAction(); virtual void closeEvent(QCloseEvent *);
private slots: void ShowMember(const QStringList &);//显示成员
void on_sendPushButton_clicked(); void kick(); void ShowMessageInfo(const QString &);//显示消息信息 void ChangeWindowTitle(const QString &);//修改窗口标题 void UpdateVersion(const QStringList &);//更新版本 void KeyPress(QKeyEvent *e); void ChangeWindowIcon();//修改窗口图标
private: Ui::MainWindow *ui; GetServerInfo *ser; int messageCount,timerCount; QStandardItemModel *memberModel; CreateDialog *createDialog; QString titile; QTimer *timer; QProcess *updateProcess;//更新进程};
#endif // MAINWINDOW_H#include "mainwindow.h"#include "ui_mainwindow.h"#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){ ui->setupUi(this); this->setFixedSize(this->size()); this->setWindowTitle(tr("TT(WGM TeamTalk) ")+VERSION); messageCount=0; timerCount=0;
updateProcess=new QProcess();
ser=new GetServerInfo(qApp->argv()[1],qApp->argv()[2],qApp->argv()[3]);
ser->ConnectToHost();
connect(ui->sendTextEdit,SIGNAL(KeyPress(QKeyEvent *)),SLOT(KeyPress(QKeyEvent *))); memberModel=new QStandardItemModel(this); memberModel->setHorizontalHeaderItem(0,new QStandardItem(QIcon(":/icon/group"),tr("MemberList")));
ui->memberTreeView->setModel(memberModel); ui->memberTreeView->setContextMenuPolicy(Qt::ActionsContextMenu); ui->memberTreeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
if(QString(qApp->argv()[2])=="admin") { createDialog=new CreateDialog(this); connect(createDialog,SIGNAL(EmitCreateTeam(QString,QString,quint8)),ser,SLOT(SendCreateTeam(QString,QString,quint8))); connect(createDialog,SIGNAL(rejected()),qApp,SLOT(quit()));
QAction *action=new QAction(QIcon(":/icon/kick"),tr("kick"),this); connect(action,SIGNAL(triggered()),SLOT(kick())); ui->memberTreeView->addAction(action);
}else { ser->Login(); }
timer=new QTimer(this); connect(timer,SIGNAL(timeout()),SLOT(ChangeWindowIcon()));
this->CreateAction();}
MainWindow::~MainWindow(){ delete ui;}
void MainWindow::CreateAction(){ connect(ser,SIGNAL(EmitAnnouncement(QString)),ui->announcementTextEdit,SLOT(setText(QString))); connect(ser,SIGNAL(EmitChangeAdvertising(QPixmap)),ui->advertisingLabel,SLOT(setPixmap(QPixmap))); connect(ser,SIGNAL(EmitKick()),qApp,SLOT(quit())); connect(ser,SIGNAL(EmitMessage(QString)),SLOT(ShowMessageInfo(QString))); connect(ser,SIGNAL(EmitRefreshMember(QStringList)),SLOT(ShowMember(QStringList))); connect(ser,SIGNAL(EmitChangeWindowTitle(QString)),SLOT(ChangeWindowTitle(QString))); connect(ser,SIGNAL(EmitUpdateVersion(QStringList)),SLOT(UpdateVersion(QStringList))); connect(qApp,SIGNAL(aboutToQuit()),ser,SLOT(SendQuit()));
}
void MainWindow::ShowMember(const QStringList &list)//显示成员{ memberModel->removeRows(0,memberModel->rowCount());
for(int i=0;i<list.size();++i) { memberModel->appendRow(new QStandardItem(QIcon(":/icon/admin"),list.at(i))); }}
void MainWindow::ShowMessageInfo(const QString &s){ if(!this->isActiveWindow())//窗口是否活动 { timer->start(500); messageCount++; this->setWindowTitle(tr("TT New Message(%1)").arg(messageCount)); }
ui->receiveTextBrowser->append(s);}
void MainWindow::ChangeWindowIcon(){
if(this->isActiveWindow())//窗口是否活动 { messageCount=0; this->setWindowTitle(titile); this->setWindowIcon(QIcon(":/icon/icon")); timer->stop(); } else { if(++timerCount%2) this->setWindowIcon(QIcon(":/icon/sms")); else this->setWindowIcon(QIcon(":/icon/icon")); }
}
void MainWindow::kick()//踢人{ QString id=ui->memberTreeView->currentIndex().data().toString(); ser->SendKick(id);}
void MainWindow::on_sendPushButton_clicked()//发送消息{ if(!ui->sendTextEdit->toPlainText().isEmpty()) { ser->SendMessage(ui->sendTextEdit->toPlainText()); ui->sendTextEdit->clear(); }else { ui->sendTextEdit->setFocus(Qt::MouseFocusReason); }}
void MainWindow::ChangeWindowTitle(const QString &arg)//修改窗口标题{ this->setWindowTitle(this->windowTitle()+arg); titile=this->windowTitle();}
void MainWindow::UpdateVersion(const QStringList &list){ qApp->quit(); updateProcess->setWorkingDirectory(qApp->applicationDirPath()); updateProcess->start("WGMUpdate.exe",list);}
void MainWindow::KeyPress(QKeyEvent *e){ if(e->key()==Qt::Key_Return) this->on_sendPushButton_clicked();}
void MainWindow::closeEvent(QCloseEvent *e){ if(QMessageBox::information(this,tr("Confirm Close!"),tr("You are confirm close this?"), QMessageBox::Ok,QMessageBox::Cancel)==QMessageBox::Cancel) e->ignore();}