📄 udpsession.cpp
字号:
void UdpSession::onNewUIN(UdpInPacket &in)
{
const char *pass = in.readString();
int n = sprintf(sqlStmt, "INSERT INTO basic_tbl (passwd) VALUES(password('%s'))", pass);
if (mysql_real_query(&mysql, sqlStmt, n) == 0) {
uin = (uint32) mysql_insert_id(&mysql);
n = sprintf(sqlStmt, "INSERT INTO ext_tbl (uin) VALUES(%lu)", uin);
mysql_real_query(&mysql, sqlStmt, n);
}
UdpOutPacket *out = createPacket(UDP_NEW_UIN, in.getSeq());
out->write32(uin);
sendPacket(out);
keepAliveList.add(&keepAliveItem);
SessionHash::addDead(this);
cout << uin << " has registered." << endl;
}
void UdpSession::onGetContactList(UdpInPacket &in)
{
MYSQL_RES *res;
MYSQL_ROW row;
int n = sprintf(sqlStmt, "SELECT uin2 FROM friend_tbl WHERE uin1=%lu", uin);
if (mysql_real_query(&mysql, sqlStmt, n) == 0 && (res = mysql_store_result(&mysql))) {
uint16 num = 0;
UdpOutPacket *out = createPacket(UDP_GET_CONTACTLIST, in.getSeq());
char *old = out->skip(sizeof(num));
while ((row = mysql_fetch_row(res))) {
out->write32(atol(row[0]));
num++;
}
mysql_free_result(res);
old = out->setCursor(old);
out->write16(num);
out->setCursor(old);
sendPacket(out);
}
}
void UdpSession::onLogin(UdpInPacket &in)
{
uint8 error = LOGIN_INVALID_UIN;
UdpOutPacket *out;
uint32 friendUIN;
MYSQL_RES *res;
MYSQL_ROW row;
uin = in.getUIN();
const char *pass = in.readString();
status = in.read32();
tcpVer = in.read16();
realIP = in.read32();
int n = sprintf(sqlStmt, "SELECT auth FROM basic_tbl WHERE uin=%lu AND passwd=password('%s')", uin, pass);
if (mysql_real_query(&mysql, sqlStmt, n) == 0 && (res = mysql_store_result(&mysql))) {
row = mysql_fetch_row(res);
if (row) {
auth = atoi(row[0]);
error = LOGIN_SUCCESS;
}
mysql_free_result(res);
}
out = createPacket(UDP_LOGIN, in.getSeq());
out->write8(error);
sendPacket(out);
keepAliveList.add(&keepAliveItem);
if (error != LOGIN_SUCCESS) {
cout << uin << " login failed." << endl;
SessionHash::addDead(this);
return;
}
strncpy(passwd, pass, 8);
cout << uin << " successfully logged in." << endl;
UdpSession *session = SessionHash::getAlive(uin);
if (session) {
cout << "previous session exists, delete it." << endl;
delete session;
session = NULL;
}
SessionHash::addAlive(this);
// inform me of my friends' status.
n = sprintf(sqlStmt, "SELECT uin2 FROM friend_tbl WHERE uin1=%lu", uin);
if (mysql_real_query(&mysql, sqlStmt, n) == 0 && (res = mysql_store_result(&mysql))) {
uint16 num = 0;
out = createPacket(UDP_SRV_MULTI_ONLINE);
char *old = out->skip(sizeof(num));
while ((row = mysql_fetch_row(res))) {
friendUIN = atol(row[0]);
UdpSession *session = SessionHash::getAlive(friendUIN);
if (session && session->status != STATUS_INVIS) {
num++;
out->write32(friendUIN);
out->write32(session->status);
out->write32(session->ip);
out->write16(session->port);
out->write32(session->realIP);
cout << "friend " << friendUIN << " is online" << endl;
}
}
if (num) {
old = out->setCursor(old);
out->write16(num);
out->setCursor(old);
sendPacket(out);
} else {
sendSeq--;
delete out;
}
mysql_free_result(res);
}
// I am now online!
if (status == STATUS_OFFLINE)
status = STATUS_ONLINE;
if (status != STATUS_INVIS)
onlineNotify();
// Broadcast messages
n = sprintf(sqlStmt, "SELECT src, type, time, msg FROM broadmsg_tbl a, broadmsg_content_tbl b "
"WHERE dst=%lu AND a.id=b.id", uin);
sendMessages(sqlStmt, n);
// Has someone sent me messages during offline?
n = sprintf(sqlStmt, "SELECT src, type, time, msg FROM message_tbl WHERE dst=%lu", uin);
sendMessages(sqlStmt, n);
}
void UdpSession::sendMessages(const char *sql, int n)
{
MYSQL_RES *res;
MYSQL_ROW row;
if (mysql_real_query(&mysql, sql, n) == 0 && (res = mysql_store_result(&mysql))) {
while ((row = mysql_fetch_row(res))) {
uint32 friendUIN = atol(row[0]);
uint8 type = atoi(row[1]);
time_t sendTime = atol(row[2]);
const char *text = row[3];
UdpOutPacket *out = createPacket(UDP_SRV_MESSAGE);
out->write8(type);
out->write32(friendUIN);
out->write32(sendTime);
out->writeString(text);
sendPacket(out);
}
mysql_free_result(res);
}
}
void UdpSession::sendMessage(uint8 type, uint32 dst, uint32 src, UdpSession *dstSession, time_t when, const char *text)
{
if (dstSession) {
UdpOutPacket *out = dstSession->createPacket(UDP_SRV_MESSAGE);
out->write8(type);
out->write32(src);
out->write32(when);
out->writeString(text);
dstSession->sendPacket(out);
} else {
int n = sprintf(sqlStmt, "INSERT INTO message_tbl values(%lu, %lu, %d, %lu, '%s')",
dst, src, (int) type, when, text);
mysql_real_query(&mysql, sqlStmt, n);
}
}
void UdpSession::onUpdateContact(UdpInPacket &in)
{
uint32 dst = in.read32();
MYSQL_RES *res;
MYSQL_ROW row;
int n = sprintf(sqlStmt, "SELECT pic, nick, age, gender, country, province, city, email,"
"address, zipcode, tel, name, blood, college, profession, homepage, intro "
"FROM basic_tbl a, ext_tbl b WHERE a.uin=%lu AND a.uin=b.uin", dst);
if (mysql_real_query(&mysql, sqlStmt, n) == 0 && (res = mysql_store_result(&mysql))) {
row = mysql_fetch_row(res);
if (row) {
UdpOutPacket *out = createPacket(UDP_UPDATE_CONTACT, in.getSeq());
out->write32(dst);
out->write8(atoi(row[0]));
out->writeString(row[1]);
out->write8(atoi(row[2]));
out->write8(atoi(row[3]));
out->writeString(row[4]);
out->writeString(row[5]);
out->writeString(row[6]);
out->writeString(row[7]);
out->writeString(row[8]);
out->writeString(row[9]);
out->writeString(row[10]);
out->writeString(row[11]);
out->write8(atoi(row[12]));
out->writeString(row[13]);
out->writeString(row[14]);
out->writeString(row[15]);
out->writeString(row[16]);
sendPacket(out);
}
mysql_free_result(res);
}
}
void UdpSession::onUpdateUser(UdpInPacket &in)
{
MYSQL_RES *res;
MYSQL_ROW row;
int n = sprintf(sqlStmt, "SELECT pic, nick, age, gender, country, province, city, email, "
"address, zipcode, tel, name, blood, college, profession, homepage, intro "
"FROM basic_tbl a, ext_tbl b WHERE a.uin=%lu AND a.uin=b.uin", uin);
if (mysql_real_query(&mysql, sqlStmt, n) == 0 && (res = mysql_store_result(&mysql))) {
row = mysql_fetch_row(res);
if (row) {
UdpOutPacket *out = createPacket(UDP_UPDATE_USER, in.getSeq());
out->write8(atoi(row[0]));
out->writeString(row[1]);
out->write8(atoi(row[2]));
out->write8(atoi(row[3]));
out->writeString(row[4]);
out->writeString(row[5]);
out->writeString(row[6]);
out->writeString(row[7]);
out->writeString(row[8]);
out->writeString(row[9]);
out->writeString(row[10]);
out->writeString(row[11]);
out->write8(atoi(row[12]));
out->writeString(row[13]);
out->writeString(row[14]);
out->writeString(row[15]);
out->writeString(row[16]);
out->write8(auth);
sendPacket(out);
}
mysql_free_result(res);
}
}
void UdpSession::onModifyUser(UdpInPacket &in)
{
int pic = in.read8();
const char *nick = in.readString();
int age = in.read8();
int gender = in.read8();
const char *country = in.readString();
const char *province = in.readString();
const char *city = in.readString();
const char *email = in.readString();
const char *address = in.readString();
const char *zipcode = in.readString();
const char *tel = in.readString();
const char *name = in.readString();
int blood = in.read8();
const char *college = in.readString();
const char *profession = in.readString();
const char *homepage = in.readString();
const char *intro = in.readString();
auth = in.read8();
uint8 modifyPasswd = in.read8();
char *p = sqlStmt;
p += sprintf(p, "UPDATE basic_tbl SET ");
if (modifyPasswd) {
const char *pass = in.readString();
if (*pass)
p += sprintf(p, "passwd=password('%s'), ", pass);
}
p += sprintf(p, "nick='%s', pic=%d, gender=%d, age=%d, country='%s', province='%s', city='%s', email='%s', auth=%d "
"WHERE uin=%lu", nick, pic, gender, age, country, province, city, email, auth, uin);
int n = p - sqlStmt;
mysql_real_query(&mysql, sqlStmt, n);
n = sprintf(sqlStmt, "UPDATE ext_tbl SET "
"address='%s', zipcode='%s', tel='%s', "
"name='%s', blood=%d, college='%s', profession='%s', homepage='%s', intro='%s' WHERE uin=%lu",
address, zipcode, tel, name, blood, college, profession, homepage, intro, uin);
mysql_real_query(&mysql, sqlStmt, n);
}
void UdpSession::dead()
{
if (status != STATUS_INVIS)
offlineNotify();
status = STATUS_OFFLINE;
}
void UdpSession::onLogout(UdpInPacket &in)
{
cout << uin << " logged out." << endl;
dead();
if (sendQueue.isEmpty()) {
// delete all offline messages
int n = sprintf(sqlStmt, "DELETE FROM message_tbl WHERE dst=%lu", uin);
mysql_real_query(&mysql, sqlStmt, n);
n = sprintf(sqlStmt, "DELETE FROM broadmsg_tbl WHERE dst=%lu", uin);
mysql_real_query(&mysql, sqlStmt, n);
}
delete this;
}
void UdpSession::onChangeStatus(UdpInPacket &in)
{
uint32 oldStatus = status;
status = in.read32();
if (oldStatus == STATUS_INVIS && status != STATUS_INVIS)
onlineNotify();
else if (oldStatus != STATUS_INVIS && status == STATUS_INVIS)
offlineNotify();
else if (status != STATUS_INVIS) {
MYSQL_RES *res;
MYSQL_ROW row;
int n = sprintf(sqlStmt, "SELECT uin1 FROM friend_tbl WHERE uin2=%lu", uin);
if (mysql_real_query(&mysql, sqlStmt, n) == 0 && (res = mysql_store_result(&mysql))) {
while ((row = mysql_fetch_row(res))) {
uint32 friendUIN = atol(row[0]);
UdpSession *session = SessionHash::getAlive(friendUIN);
if (session) {
UdpOutPacket *out = session->createPacket(UDP_SRV_STATUS_CHANGED);
out->write32(uin);
out->write32(status);
session->sendPacket(out);
}
}
mysql_free_result(res);
}
}
}
void UdpSession::onKeepAlive(UdpInPacket &in)
{
cout << uin << " keeps alive" << endl;
expire = time(NULL) + KEEPALIVE_TIMEOUT;
keepAliveItem.remove();
keepAliveList.add(&keepAliveItem);
UdpOutPacket out(this);
createPacket(out, UDP_KEEPALIVE, in.getSeq());
out.write32(sessionCount);
sendDirect(&out);
}
void UdpSession::onSendMessage(UdpInPacket &in)
{
uint8 type = in.read8();
uint32 to = in.read32();
time_t when = in.read32();
const char *text = in.readString();
UdpSession *session = SessionHash::getAlive(to);
sendMessage(type, to, uin, session, when, text);
if (type == MSG_AUTH_ACCEPTED)
addFriend(uin, to, this, session);
}
void UdpSession::onBroadcastMsg(UdpInPacket &in)
{
if (uin >= START_UIN)
return;
uint8 type = in.read8();
uint32 when = in.read32();
time_t expire = in.read32();
const char *text = in.readString();
if (expire <= time(NULL) || !*text)
return;
int n = sprintf(sqlStmt, "INSERT INTO broadmsg_content_tbl "
"VALUES(NULL, %lu, %d, %lu, %lu, '%s')", uin, type, when, expire, text);
mysql_real_query(&mysql, sqlStmt, n);
BROADCAST_MSG *msg = new BROADCAST_MSG;
msg->id = (uint32) mysql_insert_id(&mysql);
msg->type = type;
msg->src = uin;
msg->when = when;
strncpy(msg->text, text, MAX_MSG_LEN);
msg->expire = expire;
msg->to = START_UIN;
MYSQL_RES *res;
MYSQL_ROW row;
static const char sql[] = "SELECT MAX(uin) FROM basic_tbl";
if (mysql_real_query(&mysql, sql, sizeof(sql) - 1) == 0 && (res = mysql_store_result(&mysql))) {
row = mysql_fetch_row(res);
if (row)
msg->maxUIN = atoi(row[0]);
mysql_free_result(res);
}
broadMsgList.add(&msg->listItem);
}
void UdpSession::onGroupSendMessage(UdpInPacket &in)
{
uint8 type = in.read8();
time_t when = in.read32();
const char *text = in.readString();
int n = in.read16();
while (n-- > 0) {
uint32 to = in.read32();
UdpSession *session = SessionHash::getAlive(to);
sendMessage(type, to, uin, session, when, text);
}
}
void UdpSession::onSearchRandom(UdpInPacket &in)
{
uint32 results[MAX_SEARCH_PER_PAGE];
uint16 n = SessionHash::random(results, MAX_SEARCH_PER_PAGE);
UdpOutPacket *out = createPacket(UDP_SRV_SEARCH, in.getSeq());
out->write16(n);
if (n > 0) {
MYSQL_RES *res;
MYSQL_ROW row;
static const char sql[] = "SELECT uin, pic, nick, province FROM basic_tbl WHERE uin IN(";
memcpy(sqlStmt, sql, sizeof(sql));
char *p = sqlStmt + sizeof(sql) - 1;
for (int i = 0; i < n; i++)
p += sprintf(p, "%lu,", results[i]);
*(p - 1) = ')';
if (mysql_real_query(&mysql, sqlStmt, p - sqlStmt) == 0 &&
(res = mysql_store_result(&mysql))) {
while ((row = mysql_fetch_row(res))) {
uint32 contactUIN = atoi(row[0]);
uint8 pic = atoi(row[1]);
const char *nick = row[2];
const char *province = row[3];
out->write32(contactUIN);
out->write8(1); // online
out->write8(pic);
out->writeString(nick);
out->writeString(province);
}
mysql_free_result(res);
}
}
sendPacket(out);
}
void UdpSession::onSearchCustom(UdpInPacket &in)
{
uint32 uin = in.read32();
const char *nick = in.readString();
const char *email = in.readString();
uint32 startUIN = in.read32();
int n;
if (uin != 0) {
n = sprintf(sqlStmt, "SELECT uin, pic, nick, province FROM basic_tbl WHERE uin=%lu LIMIT %d",
uin, MAX_SEARCH_PER_PAGE);
} else if (*nick || *email) {
char *p = sqlStmt;
p += sprintf(p, "SELECT uin, pic, nick, province FROM basic_tbl WHERE uin>%lu AND ", startUIN);
if (*nick)
p += sprintf(p, "nick='%s'", nick);
if (*email) {
if (*nick)
p += sprintf(p, " AND ");
p += sprintf(p, "email='%s'", email);
}
p += sprintf(p, " LIMIT %d", MAX_SEARCH_PER_PAGE);
n = p - sqlStmt;
} else {
cout << "unknown search mode" << endl;
return;
}
MYSQL_RES *res;
MYSQL_ROW row;
UdpOutPacket *out;
if (mysql_real_query(&mysql, sqlStmt, n) == 0 && (res = mysql_store_result(&mysql))) {
uint16 num = 0;
out = createPacket(UDP_SRV_SEARCH, in.getSeq());
char *old = out->skip(sizeof(num));
while ((row = mysql_fetch_row(res))) {
uint32 contactUIN = atoi(row[0]);
uint8 pic = atoi(row[1]);
const char *nick = row[2];
const char *province = row[3];
out->write32(contactUIN);
out->write8(SessionHash::getAlive(contactUIN) ? 1 : 0);
out->write8(pic);
out->writeString(nick);
out->writeString(province);
num++;
}
mysql_free_result(res);
old = out->setCursor(old);
out->write16(num);
out->setCursor(old);
sendPacket(out);
}
}
void UdpSession::onAddFriend(UdpInPacket &in)
{
uint32 dst = in.read32();
uint8 dstAuth = 0;
UdpSession *dstSession = SessionHash::getAlive(dst);
if (dstSession)
dstAuth = dstSession->auth;
else {
MYSQL_RES *res;
MYSQL_ROW row;
int n = sprintf(sqlStmt, "SELECT auth FROM basic_tbl WHERE uin=%lu", dst);
if (mysql_real_query(&mysql, sqlStmt, n) == 0 && (res = mysql_store_result(&mysql))) {
row = mysql_fetch_row(res);
if (row)
dstAuth = atoi(row[0]);
mysql_free_result(res);
}
}
UdpOutPacket *out = createPacket(UDP_ADD_FRIEND, in.getSeq());
out->write32(dst);
out->write8(dstAuth);
sendPacket(out);
if (dstAuth == ADD_FRIEND_ACCEPTED) {
addFriend(dst, uin, dstSession, this);
sendMessage(MSG_ADDED, dst, uin, dstSession, time(NULL), "");
}
}
void UdpSession::onDelFriend(UdpInPacket &in)
{
uint32 dst = in.read32();
int n = sprintf(sqlStmt, "DELETE FROM friend_tbl WHERE uin1=%lu AND uin2=%lu", uin, dst);
mysql_real_query(&mysql, sqlStmt, n);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -