330 lines
11 KiB
C++
330 lines
11 KiB
C++
#include "precompile.h"
|
|
|
|
#include <a8/openssl.h>
|
|
#include <a8/mutable_xobject.h>
|
|
|
|
#include "guild.h"
|
|
#include "guildmgr.h"
|
|
#include "cs_msgid.pb.h"
|
|
#include "ss_msgid.pb.h"
|
|
#include "cs_proto.pb.h"
|
|
#include "ss_proto.pb.h"
|
|
#include "IMListener.h"
|
|
#include "asynctaskmgr.h"
|
|
#include "dbengine.h"
|
|
#include "jsondatamgr.h"
|
|
#include "player.h"
|
|
#include "playermgr.h"
|
|
#include "app.h"
|
|
#include "typeconvert.h"
|
|
#include "handlermgr.h"
|
|
#include "synchelper.h"
|
|
|
|
#include "framework/cpp/httpclientpool.h"
|
|
|
|
class AsyncGuildTask
|
|
{
|
|
public:
|
|
int socket_handle = 0;
|
|
long long guild_id = 0;
|
|
time_t time = 0;
|
|
ss::SS_IM_ForwardGuildCMMsg forward_msg;
|
|
|
|
void Execute(Guild* guild)
|
|
{
|
|
f8::NetMsgHandler* handler = f8::GetNetMsgHandler(&HandlerMgr::Instance()->guild_msghandler,
|
|
forward_msg.msgid());
|
|
if (handler && handler->handlerid == HID_Guild) {
|
|
f8::MsgHdr hdr;
|
|
hdr.seqid = 0;
|
|
hdr.msgid = forward_msg.msgid();
|
|
hdr.socket_handle = socket_handle;
|
|
hdr.ip_saddr = 0;
|
|
hdr.buf = forward_msg.payload().data();
|
|
hdr.buflen = forward_msg.payload().size();
|
|
hdr.offset = 0;
|
|
hdr.hum = nullptr;
|
|
hdr.user_data = &forward_msg;
|
|
if (guild->Status() == kGuildDismissed) {
|
|
cs::SMShowErrorMsg notifymsg;
|
|
notifymsg.set_msg("公会已解散");
|
|
GuildMgr::Instance()->ForwardGuildSMMsg(socket_handle,
|
|
forward_msg.context(),
|
|
notifymsg);
|
|
SyncHelper::Instance()->SyncGuildMemberQuit
|
|
(guild,
|
|
forward_msg.context().user_info().base_data().account_id(),
|
|
forward_msg.context().user_info().base_data().account_id(),
|
|
kGuildDismisss);
|
|
} else {
|
|
guild->Active();
|
|
ProcessNetMsg(handler, guild, hdr);
|
|
}
|
|
}
|
|
}
|
|
|
|
void OnError()
|
|
{
|
|
cs::SMShowErrorMsg notifymsg;
|
|
notifymsg.set_msg("服务器内部错误");
|
|
GuildMgr::Instance()->ForwardGuildSMMsg(socket_handle,
|
|
forward_msg.context(),
|
|
notifymsg);
|
|
}
|
|
};
|
|
|
|
void GuildMgr::Init()
|
|
{
|
|
|
|
}
|
|
|
|
void GuildMgr::UnInit()
|
|
{
|
|
for (auto& pair : id_hash_) {
|
|
delete pair.second;
|
|
}
|
|
id_hash_.clear();
|
|
for (auto& pair : task_hash_) {
|
|
for (auto task :pair.second) {
|
|
delete task;
|
|
}
|
|
}
|
|
task_hash_.clear();
|
|
}
|
|
|
|
void GuildMgr::_SS_IM_ForwardGuildCMMsg(f8::MsgHdr& hdr, const ss::SS_IM_ForwardGuildCMMsg& msg)
|
|
{
|
|
if (msg.msgid() < cs::CMMessageId_e::_CMGuildMsgBegin ||
|
|
msg.msgid() > cs::CMMessageId_e::_CMGuildMsgEnd) {
|
|
return;
|
|
}
|
|
if (!IsValidGuildId(msg.guild_id())) {
|
|
cs::SMShowErrorMsg respmsg;
|
|
respmsg.set_msg("服务器内部错误");
|
|
ForwardGuildSMMsg(hdr.socket_handle, msg.context(), respmsg);
|
|
return;
|
|
}
|
|
AsyncGuildTask *task = new AsyncGuildTask();
|
|
task->forward_msg = msg;
|
|
CreateAsyncTask(hdr.socket_handle, msg.guild_id(), task);
|
|
}
|
|
|
|
void GuildMgr::_SS_IM_ForwardGuildSMMsg(f8::MsgHdr& hdr, const ss::SS_IM_ForwardGuildSMMsg& msg)
|
|
{
|
|
Player* hum = PlayerMgr::Instance()->GetPlayerByAccountId
|
|
(msg.context().user_info().base_data().account_id());
|
|
if (hum) {
|
|
WSListener::Instance()->SendRawDataToClient(hum->socket_handle, msg.msgid(), msg.payload());
|
|
}
|
|
}
|
|
|
|
void GuildMgr::_SS_IM_RefeshGuildMemberInfo(f8::MsgHdr& hdr, const ss::SS_IM_RefeshGuildMemberInfo& msg)
|
|
{
|
|
Guild* guild = GetGuild(msg.context().user_info().base_data().guild_id());
|
|
if (guild) {
|
|
guild->UpdateMemberInfo(msg.context().user_info());
|
|
} else {
|
|
if (msg.context().user_info().base_data().guild_id() != 0) {
|
|
LoadGuild(msg.context().user_info().base_data().guild_id());
|
|
}
|
|
}
|
|
}
|
|
|
|
void GuildMgr::_SS_IM_PushGuildUserOnlineState(f8::MsgHdr& hdr, const ss::SS_IM_PushGuildUserOnlineState& msg)
|
|
{
|
|
Guild* guild = GetGuild(msg.guild_id());
|
|
if (guild) {
|
|
for (auto& account_id : msg.online_users()) {
|
|
guild->UpdateMemberOnline(account_id);
|
|
}
|
|
}
|
|
}
|
|
|
|
void GuildMgr::CreateAsyncTask(int socket_handle, long long guild_id, AsyncGuildTask* task)
|
|
{
|
|
Guild* guild = GetGuild(guild_id);
|
|
if (guild) {
|
|
task->Execute(guild);
|
|
delete task;
|
|
return;
|
|
}
|
|
task->socket_handle = socket_handle;
|
|
task->guild_id = guild_id;
|
|
task->time = App::Instance()->nowtime;
|
|
auto itr = task_hash_.find(guild_id);
|
|
if (itr != task_hash_.end()) {
|
|
itr->second.push_back(task);
|
|
} else {
|
|
task_hash_[guild_id] = std::list<AsyncGuildTask*>({task});
|
|
LoadGuild(guild_id);
|
|
}
|
|
}
|
|
|
|
void GuildMgr::LoadGuild(long long guild_id)
|
|
{
|
|
if (pending_guild_hash_.find(guild_id) != pending_guild_hash_.end()) {
|
|
return;
|
|
}
|
|
pending_guild_hash_.insert(guild_id);
|
|
|
|
auto on_ok =
|
|
[] (a8::XParams& param, const f8::DataSet* data_set)
|
|
{
|
|
GuildMgr::Instance()->pending_guild_hash_.erase(param.sender);
|
|
Guild* guild = nullptr;
|
|
if (data_set) {
|
|
for (auto& row : *data_set) {
|
|
guild = Guild::CreateGuild
|
|
(
|
|
a8::XValue(row[0]), //gameid
|
|
a8::XValue(row[1]), //guild_id
|
|
row[2], //guild_name
|
|
a8::XValue(row[3]), //guild_lv
|
|
a8::XValue(row[4]), //guild_exp
|
|
a8::XValue(row[5]), //guild_badge
|
|
a8::XValue(row[6]), //guild_apply_num
|
|
row[7], //guild_members
|
|
row[8], //guild_notice
|
|
row[9], //guild_declaration
|
|
row[10], //guild_log
|
|
row[11], //owner_id
|
|
row[12], //owner_name
|
|
row[13], //owner_avatar_url
|
|
row[14], //creator_id
|
|
row[15], //creator_name
|
|
row[16], //creator_avatar_url
|
|
row[17], //guild_data
|
|
a8::XValue(row[18]), //guild_status
|
|
a8::XValue(row[19]), //join_unlimited
|
|
a8::XValue(row[20]), //join_cond1
|
|
a8::XValue(row[21]), //join_cond2
|
|
a8::XValue(row[22]), //createtime
|
|
a8::XValue(row[23]) //channel
|
|
);
|
|
GuildMgr::Instance()->id_hash_[guild->GuildId()] = guild;
|
|
break;
|
|
}
|
|
}//end if
|
|
GuildMgr::Instance()->pending_guild_hash_.erase(param.sender);
|
|
auto itr = GuildMgr::Instance()->task_hash_.find(param.sender);
|
|
if (itr != GuildMgr::Instance()->task_hash_.end()) {
|
|
for (auto task : itr->second) {
|
|
if (guild) {
|
|
task->Execute(guild);
|
|
} else {
|
|
task->OnError();
|
|
}
|
|
delete task;
|
|
}
|
|
GuildMgr::Instance()->task_hash_.erase(itr);
|
|
}
|
|
};
|
|
auto on_error =
|
|
[] (a8::XParams& param, int error_code, const std::string& error_msg)
|
|
{
|
|
GuildMgr::Instance()->pending_guild_hash_.erase(param.sender);
|
|
auto itr = GuildMgr::Instance()->task_hash_.find(param.sender);
|
|
if (itr != GuildMgr::Instance()->task_hash_.end()) {
|
|
for (auto task : itr->second) {
|
|
task->OnError();
|
|
delete task;
|
|
}
|
|
GuildMgr::Instance()->task_hash_.erase(itr);
|
|
}
|
|
};
|
|
|
|
a8::XObject conn_info = DBEngine::Instance()->GetConnInfo(guild_id);
|
|
DBEngine::Instance()->ExecAsyncQuery
|
|
(
|
|
conn_info,
|
|
"SELECT gameid, guild_id, guild_name, guild_lv, guild_exp, guild_badge, guild_apply_num, "
|
|
" guild_members, guild_notice, guild_declaration, guild_log, "
|
|
" owner_id, owner_name, owner_avatar_url, "
|
|
" creator_id, creator_name, creator_avatar_url, guild_data, guild_status, "
|
|
" join_unlimited, join_cond1, join_cond2, createtime, channel "
|
|
"FROM `guild` WHERE guild_id=%d;",
|
|
{
|
|
guild_id
|
|
},
|
|
a8::XParams()
|
|
.SetSender(guild_id),
|
|
on_ok,
|
|
on_error,
|
|
guild_id
|
|
);
|
|
}
|
|
|
|
bool GuildMgr::IsValidGuildId(long long guild_id)
|
|
{
|
|
return JsonDataMgr::Instance()->GetIMInstanceId(guild_id) == App::Instance()->instance_id;
|
|
}
|
|
|
|
Guild* GuildMgr::GetGuild(long long guild_id)
|
|
{
|
|
auto itr = id_hash_.find(guild_id);
|
|
return itr != id_hash_.end() ? itr->second : nullptr;
|
|
}
|
|
|
|
void GuildMgr::ForwardGuildSMMsg(int socket_handle,
|
|
const ss::MFIMMsgConext& context,
|
|
int msgid,
|
|
const ::google::protobuf::Message& smmsg)
|
|
{
|
|
ss::SS_IM_ForwardGuildSMMsg msg;
|
|
*msg.mutable_context() = context;
|
|
msg.set_msgid(msgid);
|
|
smmsg.SerializeToString(msg.mutable_payload());
|
|
if (socket_handle == 0) {
|
|
int packlen = msg.ByteSize();
|
|
char* buff = nullptr;
|
|
if (packlen > 0) {
|
|
buff = (char*)malloc(packlen);
|
|
msg.SerializeToArray(buff, packlen);
|
|
}
|
|
App::Instance()->AddSocketMsg
|
|
(
|
|
SF_IMServer,
|
|
0,
|
|
0,
|
|
ss::SSMessageId_e::_SS_IM_ForwardGuildSMMsg,
|
|
0,
|
|
buff,
|
|
packlen
|
|
);
|
|
if (buff) {
|
|
free(buff);
|
|
}
|
|
} else {
|
|
IMListener::Instance()->SendMsg(socket_handle, msg);
|
|
}
|
|
}
|
|
|
|
void GuildMgr::SendMsg(int socket_handle,
|
|
int msgid,
|
|
const ::google::protobuf::Message& msg)
|
|
{
|
|
if (socket_handle == 0) {
|
|
int packlen = msg.ByteSize();
|
|
char* buff = nullptr;
|
|
if (packlen > 0) {
|
|
buff = (char*)malloc(packlen);
|
|
msg.SerializeToArray(buff, packlen);
|
|
}
|
|
App::Instance()->AddSocketMsg
|
|
(
|
|
SF_IMServer,
|
|
0,
|
|
0,
|
|
msgid,
|
|
0,
|
|
buff,
|
|
packlen
|
|
);
|
|
if (buff) {
|
|
free(buff);
|
|
}
|
|
} else {
|
|
IMListener::Instance()->SendMsg(socket_handle, msg);
|
|
}
|
|
}
|