356 lines
12 KiB
C++
356 lines
12 KiB
C++
#include "precompile.h"
|
|
|
|
#include <a8/openssl.h>
|
|
#include <a8/udplog.h>
|
|
|
|
#include "playermgr.h"
|
|
#include "player.h"
|
|
#include "cs_proto.pb.h"
|
|
#include "dbengine.h"
|
|
#include "WSListener.h"
|
|
#include "app.h"
|
|
|
|
#include "framework/cpp/utils.h"
|
|
|
|
void PlayerMgr::Init()
|
|
{
|
|
}
|
|
|
|
void PlayerMgr::UnInit()
|
|
{
|
|
}
|
|
|
|
void PlayerMgr::_SS_WSP_SocketDisconnect(f8::MsgHdr& hdr, const ss::SS_WSP_SocketDisconnect& msg)
|
|
{
|
|
OnClientSocketDisconnect(hdr.socket_handle);
|
|
}
|
|
|
|
void PlayerMgr::_SS_MS_PushUserList(f8::MsgHdr& hdr, const ss::SS_MS_PushUserList& msg)
|
|
{
|
|
|
|
}
|
|
|
|
void PlayerMgr::_SS_IM_SendChatMsg(f8::MsgHdr& hdr, const ss::SS_IM_SendChatMsg& msg)
|
|
{
|
|
|
|
}
|
|
|
|
void PlayerMgr::_SS_IM_SendCustomMsg(f8::MsgHdr& hdr, const ss::SS_IM_SendCustomMsg& msg)
|
|
{
|
|
|
|
}
|
|
|
|
void PlayerMgr::_SS_IM_UpdateUserInfo(f8::MsgHdr& hdr, const ss::SS_IM_UpdateUserInfo& msg)
|
|
{
|
|
|
|
}
|
|
|
|
void PlayerMgr::_CMLogin(f8::MsgHdr& hdr, const cs::CMLogin& msg)
|
|
{
|
|
Player* hum = GetPlayerByAccountId(msg.account_id());
|
|
if (hum) {
|
|
hum->ReLogin(hdr, msg);
|
|
return;
|
|
}
|
|
if (GetHdrBySocket(hdr.socket_handle) ||
|
|
GetHdrByAccountId(msg.account_id())) {
|
|
cs::SMLogin respmsg;
|
|
respmsg.set_errcode(1);
|
|
respmsg.set_errmsg("登录失败请重试");
|
|
WSListener::Instance()->SendToClient(hdr.socket_handle, 0, respmsg);
|
|
return;
|
|
}
|
|
f8::MsgHdr* new_hdr = hdr.Clone();
|
|
pending_socket_hash_[hdr.socket_handle] = std::make_tuple(msg.account_id(), new_hdr);
|
|
pending_account_hash_[msg.account_id()] = new_hdr;
|
|
AsyncLogin1(msg);
|
|
}
|
|
|
|
int PlayerMgr::OnlineNum()
|
|
{
|
|
return socket_hash_.size();
|
|
}
|
|
|
|
Player* PlayerMgr::GetPlayerBySocket(int socket)
|
|
{
|
|
auto itr = socket_hash_.find(socket);
|
|
return itr != socket_hash_.end() ? itr->second : nullptr;
|
|
}
|
|
|
|
Player* PlayerMgr::GetPlayerByAccountId(const std::string& account_id)
|
|
{
|
|
auto itr = accountid_hash_.find(account_id);
|
|
return itr != accountid_hash_.end() ? itr->second : nullptr;
|
|
}
|
|
|
|
void PlayerMgr::ReBindSocket(int socket_handle, Player* hum)
|
|
{
|
|
socket_hash_.erase(hum->socket_handle);
|
|
socket_hash_[socket_handle] = hum;
|
|
hum->socket_handle = socket_handle;
|
|
}
|
|
|
|
void PlayerMgr::OnWSProxyDisconnect(a8::XParams& param)
|
|
{
|
|
int ws_socket = param.sender;
|
|
|
|
std::vector<int> socket_list;
|
|
for (auto& pair : socket_hash_) {
|
|
unsigned short parent_socket_handle = (pair.first >> 16) & 0xFFFF;
|
|
if (parent_socket_handle == ws_socket) {
|
|
socket_list.push_back(pair.first);
|
|
}
|
|
}
|
|
for (int socket_handle : socket_list) {
|
|
OnClientSocketDisconnect(socket_handle);
|
|
}
|
|
a8::UdpLog::Instance()->Warning
|
|
(
|
|
"OnWSProxyDisconnect %d",
|
|
{
|
|
ws_socket
|
|
});
|
|
}
|
|
|
|
void PlayerMgr::OnClientDisconnect(a8::XParams& param)
|
|
{
|
|
int gg_socket = param.sender;
|
|
|
|
std::vector<int> socket_list;
|
|
for (auto& pair : socket_hash_) {
|
|
unsigned short parent_socket_handle = (pair.first >> 16) & 0xFFFF;
|
|
if (parent_socket_handle == gg_socket) {
|
|
socket_list.push_back(pair.first);
|
|
}
|
|
}
|
|
for (int socket_handle : socket_list) {
|
|
Player* hum = GetPlayerBySocket(socket_handle);
|
|
if (hum) {
|
|
RemovePlayerBySocket(socket_handle);
|
|
}
|
|
}
|
|
}
|
|
|
|
void PlayerMgr::RemovePlayerBySocket(int socket_handle)
|
|
{
|
|
auto itr = socket_hash_.find(socket_handle);
|
|
if (itr != socket_hash_.end()) {
|
|
itr->second->socket_handle = 0;
|
|
socket_hash_.erase(itr);
|
|
}
|
|
}
|
|
|
|
f8::MsgHdr* PlayerMgr::GetHdrBySocket(int socket_handle)
|
|
{
|
|
auto itr = pending_socket_hash_.find(socket_handle);
|
|
return itr != pending_socket_hash_.end() ? std::get<1>(itr->second) : nullptr;
|
|
}
|
|
|
|
f8::MsgHdr* PlayerMgr::GetHdrByAccountId(const std::string& account_id)
|
|
{
|
|
auto itr = pending_account_hash_.find(account_id);
|
|
return itr != pending_account_hash_.end() ? itr->second : nullptr;
|
|
}
|
|
|
|
void PlayerMgr::AsyncLogin1(const cs::CMLogin& msg)
|
|
{
|
|
auto on_ok =
|
|
[] (a8::XParams& param, const f8::DataSet* data_set)
|
|
{
|
|
cs::CMLogin* msg = (cs::CMLogin*)param.sender.GetUserData();
|
|
PlayerMgr::Instance()->AsyncLogin2(*msg);
|
|
delete msg;
|
|
};
|
|
auto on_error =
|
|
[] (a8::XParams& param, int error_code, const std::string& error_msg)
|
|
{
|
|
cs::CMLogin* msg = (cs::CMLogin*)param.sender.GetUserData();
|
|
PlayerMgr::Instance()->AsyncLoginOnError(
|
|
msg->account_id(),
|
|
1,
|
|
1,
|
|
""
|
|
);
|
|
delete msg;
|
|
};
|
|
cs::CMLogin* msg_copy = new cs::CMLogin();
|
|
*msg_copy = msg;
|
|
a8::XObject conn_info = DBEngine::Instance()->GetConnInfo(msg.account_id());
|
|
DBEngine::Instance()->ExecAsyncScript
|
|
(conn_info,
|
|
"INSERT INTO `user`(account_id, nickname, avatar_url,"
|
|
" sex, friend_data, createtime, modifytime, registertime)"
|
|
"VALUES ('%s', '%s', '%s', %d, '', %d, %d, %d)"
|
|
"ON DUPLICATE KEY UPDATE nickname='%s', avatar_url='%s',"
|
|
" sex=%d, last_logintime=%d, data_version1=data_version1 + 1;",
|
|
{
|
|
msg.account_id(),
|
|
msg.nickname(),
|
|
msg.avatar_url(),
|
|
msg.sex(),
|
|
App::Instance()->nowtime,
|
|
App::Instance()->nowtime,
|
|
f8::ExtractRegisterTimeFromSessionId(msg.session_id()),
|
|
msg.nickname(),
|
|
msg.avatar_url(),
|
|
msg.sex(),
|
|
App::Instance()->nowtime
|
|
},
|
|
a8::XParams()
|
|
.SetSender((void*)msg_copy),
|
|
on_ok,
|
|
on_error,
|
|
a8::openssl::Crc32((unsigned char*)msg.account_id().data(),
|
|
msg.account_id().size())
|
|
);
|
|
}
|
|
|
|
void PlayerMgr::AsyncLogin2(const cs::CMLogin& msg)
|
|
{
|
|
auto on_ok =
|
|
[] (a8::XParams& param, const f8::DataSet* data_set)
|
|
{
|
|
cs::CMLogin* msg = (cs::CMLogin*)param.sender.GetUserData();
|
|
if (data_set->empty()) {
|
|
PlayerMgr::Instance()->AsyncLoginOnError(
|
|
msg->account_id(),
|
|
2,
|
|
1,
|
|
""
|
|
);
|
|
} else {
|
|
PlayerMgr::Instance()->AsyncLoginOnOk(
|
|
data_set->at(0).at(0),
|
|
data_set->at(0).at(1),
|
|
data_set->at(0).at(2),
|
|
a8::XValue(data_set->at(0).at(3)),
|
|
a8::XValue(data_set->at(0).at(4)),
|
|
a8::XValue(data_set->at(0).at(6)),
|
|
a8::XValue(data_set->at(0).at(5)),
|
|
a8::XValue(data_set->at(0).at(7)),
|
|
a8::XValue(data_set->at(0).at(8)),
|
|
a8::XValue(data_set->at(0).at(9))
|
|
);
|
|
}
|
|
delete msg;
|
|
};
|
|
auto on_error =
|
|
[] (a8::XParams& param, int error_code, const std::string& error_msg)
|
|
{
|
|
cs::CMLogin* msg = (cs::CMLogin*)param.sender.GetUserData();
|
|
PlayerMgr::Instance()->AsyncLoginOnError(
|
|
msg->account_id(),
|
|
2,
|
|
1,
|
|
""
|
|
);
|
|
delete msg;
|
|
};
|
|
cs::CMLogin* msg_copy = new cs::CMLogin();
|
|
*msg_copy = msg;
|
|
a8::XObject conn_info = DBEngine::Instance()->GetConnInfo(msg.account_id());
|
|
DBEngine::Instance()->ExecAsyncQuery
|
|
(conn_info,
|
|
"SELECT account_id, nickname, avatar_url, sex, group_id, "
|
|
" data_version1, friend_data, user_value1, user_value2, user_value3 "
|
|
"FROM `user` WHERE account_id='%s';",
|
|
{
|
|
msg.account_id(),
|
|
},
|
|
a8::XParams()
|
|
.SetSender((void*)msg_copy),
|
|
on_ok,
|
|
on_error,
|
|
a8::openssl::Crc32((unsigned char*)msg.account_id().data(),
|
|
msg.account_id().size())
|
|
);
|
|
}
|
|
|
|
void PlayerMgr::AsyncLoginOnOk(const std::string& account_id,
|
|
const std::string& nickname,
|
|
const std::string& avatar_url,
|
|
int sex,
|
|
long long group_id,
|
|
const std::string& friend_data,
|
|
int data_version1,
|
|
long long user_value1,
|
|
long long user_value2,
|
|
long long user_value3)
|
|
{
|
|
f8::MsgHdr* hdr = GetHdrByAccountId(account_id);
|
|
if (hdr) {
|
|
Player* hum = GetPlayerByAccountId(account_id);
|
|
if (hum) {
|
|
abort();
|
|
}
|
|
hum = GetPlayerBySocket(hdr->socket_handle);
|
|
if (hum) {
|
|
abort();
|
|
}
|
|
{
|
|
hum = new Player();
|
|
hum->socket_handle = hdr->socket_handle;
|
|
hum->data.base_data.account_id = account_id;
|
|
hum->data.base_data.nickname = nickname;
|
|
hum->data.base_data.avatar_url = avatar_url;
|
|
hum->data.base_data.sex = sex;
|
|
hum->data.base_data.group_id = group_id;
|
|
hum->data.base_data.data_version1 = data_version1;
|
|
hum->data.base_data.user_value1 = user_value1;
|
|
hum->data.base_data.user_value2 = user_value2;
|
|
hum->data.base_data.user_value3 = user_value3;
|
|
hum->Init();
|
|
{
|
|
ss::MFUserDB user_db;
|
|
user_db.ParseFromString(friend_data);
|
|
hum->Deserialize(user_db);
|
|
}
|
|
socket_hash_[hdr->socket_handle] = hum;
|
|
accountid_hash_[account_id] = hum;
|
|
}
|
|
pending_socket_hash_.erase(hdr->socket_handle);
|
|
pending_account_hash_.erase(account_id);
|
|
f8::MsgHdr::Destroy(hdr);
|
|
}
|
|
}
|
|
|
|
void PlayerMgr::AsyncLoginOnError(const std::string& account_id, int step,
|
|
int error_code, const std::string& error_msg)
|
|
{
|
|
f8::MsgHdr* hdr = GetHdrByAccountId(account_id);
|
|
if (hdr) {
|
|
pending_socket_hash_.erase(hdr->socket_handle);
|
|
pending_account_hash_.erase(account_id);
|
|
f8::MsgHdr::Destroy(hdr);
|
|
}
|
|
}
|
|
|
|
void PlayerMgr::OnClientSocketDisconnect(int socket_handle)
|
|
{
|
|
{
|
|
auto itr = pending_socket_hash_.find(socket_handle);
|
|
if (itr != pending_socket_hash_.end()) {
|
|
pending_account_hash_.erase(std::get<0>(itr->second));
|
|
f8::MsgHdr::Destroy(std::get<1>(itr->second));
|
|
pending_socket_hash_.erase(itr);
|
|
}
|
|
}
|
|
{
|
|
Player* hum = GetPlayerBySocket(socket_handle);
|
|
if (hum) {
|
|
hum->NotifyOffline();
|
|
hum->UnInit();
|
|
socket_hash_.erase(socket_handle);
|
|
accountid_hash_.erase(hum->data.base_data.account_id);
|
|
}
|
|
}
|
|
#ifdef DEBUG
|
|
a8::UdpLog::Instance()->Debug
|
|
(
|
|
"OnClientSocketDisconnect %d",
|
|
{
|
|
socket_handle
|
|
});
|
|
#endif
|
|
}
|