forked from HaoKang-Timmy/cardgame
-
Notifications
You must be signed in to change notification settings - Fork 0
/
waitroom.cpp
168 lines (159 loc) · 6.18 KB
/
waitroom.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include "waitroom.h"
#include "ui_waitroom.h"
#include "qhostinfo.h"
#include "_21_points.h"
#include <QMessageBox>
waitroom::waitroom(TYPEGAMES typeGame, bool isServer, selectNumPlayer* s, waitserver *ws, QWidget *parent) :
QWidget(parent), typeGame(typeGame), isServer(isServer), ws(ws), s(s),
ui(new Ui::waitroom)
{
ui->setupUi(this);
this->setAttribute(Qt::WA_DeleteOnClose, true);
client = new QUdpSocket(this);
port = 2333;
client->bind(port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
//readyRead()信号是每当有新的数据来临时就被触发
connect(client, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()));
}
waitroom::~waitroom()
{
if(isServer)
delete ws;
delete client;
delete ui;
}
void waitroom::getData(QString Seatid)
{
this->Seatid = Seatid.toInt();
}
void waitroom::on_QuitRoomBtn_clicked()
{
sendMessage(ParticipantLeft);
this->close();
}
void waitroom::on_StartgameBtn_clicked()
{
sendMessage(StartgameServer);
}
void waitroom::Startgame(int playernum, QString player[])
{
switch (playernum) {
case 2: //其实对应的是2,后面以此类推
if(typeGame == _21_POINTS)
{
_21_points *twentyone = new _21_points(2, 1, Seatid);
twentyone->setPlayers(player[1], player[2]);
this->close();
twentyone->show();
}
break;
case 3:
if(typeGame == _21_POINTS)
{
_21_points *twentyone = new _21_points(3, 1, Seatid);
twentyone->setPlayers(player[1], player[2], player[3]);
this->close();
twentyone->show();
}
break;
case 4:
if(typeGame == _21_POINTS)
{
_21_points *twentyone = new _21_points(4, 1, Seatid);
twentyone->setPlayers(player[1], player[2], player[3], player[4]);
this->close();
twentyone->show();
}
break;
}
if(isServer) {
gs = new gameserver(typeGame, playernum);
}
this->~waitroom();
}
void waitroom::processPendingDatagrams()
{
while(client->hasPendingDatagrams())
{
QByteArray datagram;
//pendingDatagramSize为返回第一个在等待读取报文的size,resize函数是把datagram的size归一化到参数size的大小一样
datagram.resize(client->pendingDatagramSize());
//将读取到的不大于datagram.size()大小数据输入到datagram.data()中,datagram.data()返回的是一个字节数组中存储
//数据位置的指针
client->readDatagram(datagram.data(), datagram.size());
QDataStream in(&datagram, QIODevice::ReadOnly);//因为其属性为只读,所以是输入
int messageType; //此处的int为qint32,在Qt中,qint8为char,qint16为uint
in >> messageType; //读取1个32位长度的整型数据到messageTyep中
QString Username,localHostName,ipAddress,message;
// QString time = QDateTime::currentDateTime()
// .toString("yyyy-MM-dd hh:mm:ss");//将当前的时间转化到括号中的形式
int connect_num;
SeatStatus connected[5];
QString player[5];
QLabel* label[5];
label[1] = ui->player1;
label[2] = ui->player2;
label[3] = ui->player3;
label[4] = ui->player4;
localHostName = QHostInfo::localHostName();
QString remoteHostName;
switch(messageType)
{
case RoomStatus:
in>>connect_num;
ui->ConnectNum->setText(QString::number(connect_num));
for(int i = 1; i <= 4; i++) {
in>>connected[i]>>player[i];
if(connected[i] == Seated)
label[i]->setText(player[i]);
else if(connected[i] == Robot) {
label[i]->setText("Robot");
}
else
label[i]->setText("等待玩家加入");
}
break;
case StartgameClient:
int playernum;
in>>playernum;
for(int i = 1; i <= 4; i++)
in>>connected[i]>>player[i];
Startgame(playernum, player);
break;
case ErrMessage:
ErrCode code;
in>>remoteHostName>>message>>code;
if(localHostName == remoteHostName)
if(code == SeatFull) {
QMessageBox::information(this,tr("Error"),QStringLiteral("座位已被占用"),QMessageBox::Ok);
this->close();
} else {
QMessageBox::information(this,tr("Error"),QStringLiteral("人数不够"),QMessageBox::Ok);
}
break;
}
}
}
// 使用UDP广播发送信息,MessageType是指头文件中的枚举数据类型
//sendMessage即把本机的主机名,用户名+(消息内容后ip地址)广播出去
void waitroom::sendMessage(MessageType type)
{
QByteArray data; //字节数组
//QDataStream类是将序列化的二进制数据送到io设备,因为其属性为只写
QDataStream out(&data, QIODevice::WriteOnly);
//将type,getUserName(),localHostName按照先后顺序送到out数据流中,消息类型type在最前面
QString localHostName = QHostInfo::localHostName();
out << type;
switch(type)
{
case ParticipantLeft :
out<<Seatid;
break;
case StartgameServer :
out<<localHostName;
}
//一个udpSocket已经于一个端口bind在一起了,这里的data是out流中的data,最多可以传送8192个字节,但是建议不要超过
//512个字节,因为这样虽然可以传送成功,但是这些数据需要在ip层分组,QHostAddress::Broadcast是指发送数据的目的地址
//这里为本机所在地址的广播组内所有机器,即局域网广播发送
client->writeDatagram(data,data.length(),QHostAddress::Broadcast, port);//将data中的数据发送
}