diff --git a/server/imserver/constant.h b/server/imserver/constant.h index 559703b..087f370 100644 --- a/server/imserver/constant.h +++ b/server/imserver/constant.h @@ -31,7 +31,8 @@ enum NetHandler_e HID_Player, HID_GroupMgr, HID_IMConnMgr, - HID_SyncHelper + HID_SyncHelper, + HID_GuildMgr }; enum ReadPointFlag diff --git a/server/imserver/guild.cc b/server/imserver/guild.cc new file mode 100644 index 0000000..ba71352 --- /dev/null +++ b/server/imserver/guild.cc @@ -0,0 +1,142 @@ +#include "precompile.h" + +#include + +#include "guild.h" +#include "cs_proto.pb.h" +#include "ss_proto.pb.h" +#include "dbengine.h" +#include "app.h" + +void Guild::Init() +{ + +} + +void Guild::UnInit() +{ + for (auto& pair : member_hash_) { + delete pair.second; + } + member_hash_.clear(); +} + +GuildMember* Guild::GetMember(const std::string& account_id) +{ + auto itr = member_hash_.find(account_id); + return itr != member_hash_.end() ? itr->second : nullptr; +} + +bool Guild::IsFull() +{ + return member_hash_.size() < 100; +} + +void Guild::Rename(const std::string& new_guild_name) +{ + guild_name = new_guild_name; + MarkDirty(); +} + +void Guild::AddMember(GuildMember* member) +{ + if (member_hash_.find(member->account_id) != member_hash_.end()) { + abort(); + } + member_hash_[member->account_id] = member; + + MarkDirty(); + if (dirty_timer_) { + a8::Timer::Instance()->ModifyTimer(dirty_timer_, 100); + } +} + +void Guild::RemoveMember(const std::string& account_id) +{ + GuildMember* member = GetMember(account_id); + if (member) { + member_hash_.erase(account_id); + } + + MarkDirty(); + if (dirty_timer_) { + a8::Timer::Instance()->ModifyTimer(dirty_timer_, 100); + } +} + +void Guild::MarkDirty() +{ + if (!dirty_) { + dirty_ = true; + dirty_timer_ = a8::Timer::Instance()-> + AddDeadLineTimerAndAttach(1000 * 60, + a8::XParams() + .SetSender((void*)this), + [] (const a8::XParams& param) + { + Guild* guild = (Guild*)param.sender.GetUserData(); + guild->SaveToDB(); + }, + &timer_attacher.timer_list_, + [] (const a8::XParams& param) + { + Guild* guild = (Guild*)param.sender.GetUserData(); + guild->dirty_timer_ = nullptr; + } + ); + } +} + +void Guild::FillGuildDB(ss::MFGuildDB& guild_dto) +{ + +} + +void Guild::SaveToDB() +{ + ss::MFGuildDB guild_db; + FillGuildDB(guild_db); + std::string guild_data; + guild_db.SerializeToString(&guild_data); + + auto on_ok = + [] (a8::XParams& param, const f8::DataSet* data_set) + { + + }; + auto on_error = + [] (a8::XParams& param, int error_code, const std::string& error_msg) + { + + }; + + a8::XObject conn_info = DBEngine::Instance()->GetConnInfo(guild_id); + DBEngine::Instance()-> + ExecAsyncScript( + conn_info, + "INSERT `guild`(guild_id, guild_name, owner_id, creator_id, guild_data " + " createtime, modifytime) " + "VALUES(%d, '%s', %d, %d, '%s', %d, %d) " + "ON DUPLICATE KEY UPDATE guild_name='%s', owner_id=%d, creator_id=%d, " + " guild_data='%s', modifytime=%d;", + { + guild_id, + guild_name, + owner_id, + creator_id, + guild_data, + App::Instance()->nowtime, + App::Instance()->nowtime, + + guild_name, + owner_id, + creator_id, + guild_data, + App::Instance()->nowtime + }, + a8::XParams(), + on_ok, + on_error, + guild_id + ); +} diff --git a/server/imserver/guild.h b/server/imserver/guild.h new file mode 100644 index 0000000..50d57a8 --- /dev/null +++ b/server/imserver/guild.h @@ -0,0 +1,50 @@ +#pragma once + +#include + +struct GuildMember +{ + std::string account_id; + std::string nickname; + std::string avatar_url; + int sex = 0; + int online = 0; + long long guild_id = 0; + int data_version1 = 0; +}; + +namespace ss +{ + class MFGuildDB; +} + +struct timer_list; +class Guild +{ + public: + long long guild_id = 0; + std::string guild_name; + std::string owner_id; + std::string creator_id; + int createtime = 0; + a8::TimerAttacher timer_attacher; + + void Init(); + void UnInit(); + + bool IsFull(); + void Rename(const std::string& new_guild_name); + GuildMember* GetMember(const std::string& account_id); + void AddMember(GuildMember* member); + void RemoveMember(const std::string& account_id); + void MarkDirty(); + +private: + void FillGuildDB(ss::MFGuildDB& guild_dto); + void SaveToDB(); + +private: + bool dirty_ = false; + timer_list* dirty_timer_ = nullptr; + std::map member_hash_; +}; diff --git a/server/imserver/guildmgr.cc b/server/imserver/guildmgr.cc new file mode 100644 index 0000000..d452ec1 --- /dev/null +++ b/server/imserver/guildmgr.cc @@ -0,0 +1,237 @@ +#include "precompile.h" + +#include "guild.h" +#include "guildmgr.h" +#include "cs_msgid.pb.h" +#include "cs_proto.pb.h" +#include "ss_proto.pb.h" +#include "MSConnMgr.h" + +void GuildMgr::Init() +{ + +} + +void GuildMgr::UnInit() +{ + +} + +void GuildMgr::_SS_MS_LoadGuild(f8::MsgHdr& hdr, const ss::SS_MS_LoadGuild& msg) +{ + +} + +void GuildMgr::_SS_MS_ForwardGuildCMMsg(f8::MsgHdr& hdr, const ss::SS_MS_ForwardGuildCMMsg& msg) +{ + switch (hdr.msgid) { + case cs::CMMessageId_e::_CMGuildCreate: + { + cs::CMGuildCreate cmmsg; + cmmsg.ParseFromArray(msg.payload().data(), msg.payload().size()); + _CMGuildCreate(msg.context(), cmmsg); + } + break; + case cs::CMMessageId_e::_CMGuildJoin: + { + cs::CMGuildJoin cmmsg; + cmmsg.ParseFromArray(msg.payload().data(), msg.payload().size()); + _CMGuildJoin(msg.context(), cmmsg); + } + break; + case cs::CMMessageId_e::_CMGuildAgree: + { + cs::CMGuildAgree cmmsg; + cmmsg.ParseFromArray(msg.payload().data(), msg.payload().size()); + _CMGuildAgree(msg.context(), cmmsg); + } + break; + case cs::CMMessageId_e::_CMGuildKick: + { + cs::CMGuildKick cmmsg; + cmmsg.ParseFromArray(msg.payload().data(), msg.payload().size()); + _CMGuildKick(msg.context(), cmmsg); + } + break; + case cs::CMMessageId_e::_CMGuildQuit: + { + cs::CMGuildQuit cmmsg; + cmmsg.ParseFromArray(msg.payload().data(), msg.payload().size()); + _CMGuildQuit(msg.context(), cmmsg); + } + break; + case cs::CMMessageId_e::_CMGuildDismiss: + { + cs::CMGuildDismiss cmmsg; + cmmsg.ParseFromArray(msg.payload().data(), msg.payload().size()); + _CMGuildDismiss(msg.context(), cmmsg); + } + break; + case cs::CMMessageId_e::_CMGuildRename: + { + cs::CMGuildRename cmmsg; + cmmsg.ParseFromArray(msg.payload().data(), msg.payload().size()); + _CMGuildRename(msg.context(), cmmsg); + } + break; + default: + { + break; + } + } +} + +void GuildMgr::_CMGuildCreate(const ss::MFIMMsgConext& context, const cs::CMGuildCreate& msg) +{ + #if 0 + Guild* guild = GetGuild(context.guild_id()); + if (guild) { + cs::SMGuildCreate respmsg; + respmsg.set_errcode(1); + respmsg.set_errmsg("群id已经存在"); + ForwardGuildSMMsg(context, respmsg); + return; + } + #endif +} + +void GuildMgr::_CMGuildJoin(const ss::MFIMMsgConext& context, const cs::CMGuildJoin& msg) +{ + #if 0 + Guild* guild = GetGuild(msg.guild_id()); + if (!guild) { + cs::SMGuildJoin respmsg; + respmsg.set_errcode(1); + respmsg.set_errmsg("群id已经存在"); + ForwardGuildSMMsg(context, respmsg); + return; + } + GuildMember* member = guild->GetMember(context.account_id()); + if (member) { + cs::SMGuildJoin respmsg; + ForwardGuildSMMsg(context, respmsg); + return; + } + if (guild->IsFull()) { + cs::SMGuildJoin respmsg; + respmsg.set_errcode(2); + respmsg.set_errmsg("群已满"); + ForwardGuildSMMsg(context, respmsg); + return; + } + member = new GuildMember(); + member->account_id = context.account_id(); + member->nickname = context.nickname(); + member->avatar_url = context.avatar_url(); + member->sex = context.sex(); + member->online = 1; + member->guild_id = guild->guild_id; + member->data_version1 = context.base_data_version(); + guild->AddMember(member); + #endif +} + +void GuildMgr::_CMGuildAgree(const ss::MFIMMsgConext& context, const cs::CMGuildAgree& msg) +{ +#if 0 + Guild* guild = GetGuild(context.guild_id()); + if (!guild) { + return; + } +#endif +} + +void GuildMgr::_CMGuildKick(const ss::MFIMMsgConext& context, const cs::CMGuildKick& msg) +{ + #if 0 + Guild* guild = GetGuild(context.guild_id()); + if (!guild) { + cs::SMGuildKick respmsg; + respmsg.set_errcode(1); + respmsg.set_errmsg("群id错误"); + ForwardGuildSMMsg(context, respmsg); + return; + } + if (!guild->GetMember(msg.account_id())) { + cs::SMGuildKick respmsg; + ForwardGuildSMMsg(context, respmsg); + return; + } + guild->RemoveMember(msg.account_id()); + cs::SMGuildKick respmsg; + ForwardGuildSMMsg(context, respmsg); + return; + #endif +} + +void GuildMgr::_CMGuildQuit(const ss::MFIMMsgConext& context, const cs::CMGuildQuit& msg) +{ +#if 0 + Guild* guild = GetGuild(context.guild_id()); + if (!guild) { + cs::SMGuildQuit respmsg; + respmsg.set_errcode(1); + respmsg.set_errmsg("群id错误"); + ForwardGuildSMMsg(context, respmsg); + return; + } + if (!guild->GetMember(context.account_id())) { + cs::SMGuildQuit respmsg; + ForwardGuildSMMsg(context, respmsg); + return; + } + guild->RemoveMember(context.account_id()); + cs::SMGuildQuit respmsg; + ForwardGuildSMMsg(context, respmsg); +#endif +} + +void GuildMgr::_CMGuildDismiss(const ss::MFIMMsgConext& context, const cs::CMGuildDismiss& msg) +{ + #if 0 + Guild* guild = GetGuild(context.guild_id()); + if (!guild) { + return; + } + #endif +} + +void GuildMgr::_CMGuildRename(const ss::MFIMMsgConext& context, const cs::CMGuildRename& msg) +{ + #if 0 + Guild* guild = GetGuild(context.guild_id()); + if (!guild) { + cs::SMGuildRename respmsg; + respmsg.set_errcode(1); + respmsg.set_errmsg("群id错误"); + ForwardGuildSMMsg(context, respmsg); + return; + } + GuildMember* member = guild->GetMember(context.account_id()); + if (!member) { + cs::SMGuildRename respmsg; + respmsg.set_errcode(2); + respmsg.set_errmsg("没有权限"); + ForwardGuildSMMsg(context, respmsg); + return; + } + guild->RemoveMember(msg.new_guild_name()); + cs::SMGuildRename respmsg; + ForwardGuildSMMsg(context, respmsg); + #endif +} + +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(const ss::MFIMMsgConext& context, + const ::google::protobuf::Message& smmsg) +{ + ss::SS_MS_ForwardGuildSMMsg msg; + *msg.mutable_context() = context; + smmsg.SerializeToString(msg.mutable_payload()); + MSConnMgr::Instance()->SendMsg(msg, 0); +} diff --git a/server/imserver/guildmgr.h b/server/imserver/guildmgr.h new file mode 100644 index 0000000..5c2a645 --- /dev/null +++ b/server/imserver/guildmgr.h @@ -0,0 +1,61 @@ +#pragma once + +namespace cs +{ + class CMGuildCreate; + class CMGuildJoin; + class CMGuildAgree; + class CMGuildKick; + class CMGuildQuit; + class CMGuildDismiss; + class CMGuildRename; +} + +namespace ss +{ + class MFIMMsgConext; + class SS_MS_LoadGuild; + class SS_MS_ForwardGuildCMMsg; +} + +namespace google +{ + namespace protobuf + { + class Message; + } +} + +class Guild; +class GuildMgr : public a8::Singleton +{ + public: + enum { HID = HID_GuildMgr }; + + private: + GuildMgr() {}; + friend class a8::Singleton; + + public: + void Init(); + void UnInit(); + + void _SS_MS_LoadGuild(f8::MsgHdr& hdr, const ss::SS_MS_LoadGuild& msg); + void _SS_MS_ForwardGuildCMMsg(f8::MsgHdr& hdr, const ss::SS_MS_ForwardGuildCMMsg& msg); + + private: + void _CMGuildCreate(const ss::MFIMMsgConext& context, const cs::CMGuildCreate& msg); + void _CMGuildJoin(const ss::MFIMMsgConext& context, const cs::CMGuildJoin& msg); + void _CMGuildAgree(const ss::MFIMMsgConext& context, const cs::CMGuildAgree& msg); + void _CMGuildKick(const ss::MFIMMsgConext& context, const cs::CMGuildKick& msg); + void _CMGuildQuit(const ss::MFIMMsgConext& context, const cs::CMGuildQuit& msg); + void _CMGuildDismiss(const ss::MFIMMsgConext& context, const cs::CMGuildDismiss& msg); + void _CMGuildRename(const ss::MFIMMsgConext& context, const cs::CMGuildRename& msg); + + Guild* GetGuild(long long group_id); + void ForwardGuildSMMsg(const ss::MFIMMsgConext& context, + const ::google::protobuf::Message& smmsg); + + private: + std::map id_hash_; +}; diff --git a/server/tools/protobuild/ss_proto.proto b/server/tools/protobuild/ss_proto.proto index 8b99bb6..064b3dd 100755 --- a/server/tools/protobuild/ss_proto.proto +++ b/server/tools/protobuild/ss_proto.proto @@ -48,6 +48,16 @@ message MFGroupDB repeated MFGroupMemberDB members = 1; } +message MFGuildMemberDB +{ + optional MFBaseUserDataDB base_data = 1; //基础数据 +} + +message MFGuildDB +{ + repeated MFGuildMemberDB members = 1; +} + message MFFriendDB { optional MFBaseUserDataDB base_data = 1; //基础数据 @@ -141,6 +151,23 @@ message SS_MS_LoadGroup optional int64 group_id = 1; } +message SS_MS_ForwardGuildCMMsg +{ + optional MFIMMsgConext context = 1; + optional bytes payload = 2; +} + +message SS_MS_ForwardGuildSMMsg +{ + optional MFIMMsgConext context = 1; + optional bytes payload = 2; +} + +message SS_MS_LoadGuild +{ + optional int64 guild_id = 1; +} + message SS_IM_ReportServerInfo { optional int32 instance_id = 1;