commit c4f3714a97749cf7f92e54b0fbea6eb84810e4c0 Author: aozhiwei Date: Fri Aug 3 19:57:13 2018 +0800 add cpp directory diff --git a/cpp/netmsghandler.cc b/cpp/netmsghandler.cc new file mode 100644 index 0000000..0e1f42e --- /dev/null +++ b/cpp/netmsghandler.cc @@ -0,0 +1,13 @@ +#include + +#include +#include + +#include "protoutils.h" +#include "netmsghandler.h" + +NetMsgHandler* GetNetMsgHandler(NetMsgHandlerObject* handlers, + unsigned short msgid) +{ + return msgid < MAX_MSG_ID ? handlers->handlers[msgid] : nullptr; +} diff --git a/cpp/netmsghandler.h b/cpp/netmsghandler.h new file mode 100644 index 0000000..7bfc2a0 --- /dev/null +++ b/cpp/netmsghandler.h @@ -0,0 +1,89 @@ +#ifndef NETMSGHANDLER_H +#define NETMSGHANDLER_H + +#include +#include +#include +#include +#include + +const unsigned short MAX_MSG_ID = 2000; + +struct MsgHdr; + +struct NetMsgHandler +{ + int handlerid; + const ::google::protobuf::Message* prototype = nullptr; +}; + +struct NetMsgHandlerObject +{ + NetMsgHandler* handlers[MAX_MSG_ID] = { nullptr }; +}; + +template +static void NetMsgHandlerWrapper(InstanceType* instance, MsgHdr& hdr, NetMsgHandler* handler) +{ + MsgType msg; + bool ok = msg.ParseFromArray(hdr.buf + hdr.offset, hdr.buflen - hdr.offset); + assert(ok); + if (ok) { + struct Invoker: public NetMsgHandler + { + void (*wrapper)(InstanceType*, MsgHdr&, NetMsgHandler*); + void (InstanceType::*func)(MsgHdr&, const MsgType&); + }; + Invoker* invoker = (Invoker*)handler; + auto ptr = invoker->func; + (instance->*ptr)(hdr, msg); + } +} + +template +static void RegisterNetMsgHandler(NetMsgHandlerObject* msghandler, + void (InstanceType::*ptr)(MsgHdr&, const MsgType&) + ) +{ + MsgType dumy_msg; + static int msgid = ::Net_GetMessageId(dumy_msg); + assert(msgid >= 0 || msgid < MAX_MSG_ID); + if (msgid < 0 || msgid >= MAX_MSG_ID) { + abort(); + } + struct Invoker: public NetMsgHandler + { + void (*wrapper)(InstanceType*, MsgHdr&, NetMsgHandler*); + void (InstanceType::*func)(MsgHdr&, const MsgType&); + }; + Invoker *p = new Invoker(); + p->wrapper = &NetMsgHandlerWrapper; + p->func = ptr; + p->handlerid = InstanceType::HID; + p->prototype = ::google::protobuf::MessageFactory::generated_factory()->GetPrototype(MsgType::descriptor()); + msghandler->handlers[msgid] = p; +} + +template +static bool ProcessNetMsg(NetMsgHandler* handler, + InstanceType* instance, + MsgHdr& hdr) +{ + if(handler){ + struct Invoker: public NetMsgHandler + { + void (*wrapper)(InstanceType*, MsgHdr&, NetMsgHandler*); + void* func; + }; + Invoker *p = (Invoker*)handler; + p->wrapper(instance, hdr, p); + return true; + }else{ + return false; + } +} + +NetMsgHandler* GetNetMsgHandler(NetMsgHandlerObject* handlers, + unsigned short msgid); + +#endif diff --git a/cpp/protoutils.cc b/cpp/protoutils.cc new file mode 100644 index 0000000..a6132ef --- /dev/null +++ b/cpp/protoutils.cc @@ -0,0 +1,95 @@ +#include + +#include "protoutils.h" + +#include +#include + +#include +#include + +int Net_GetMessageId(::google::protobuf::Message& msg) +{ + std::string msgname; + { + std::string full_msgname = msg.GetTypeName(); + std::vector strings; + a8::Split(full_msgname, strings, '.'); + msgname = strings[strings.size() - 1]; + } + assert(msgname.size() > 2); + if (msgname.size() < 2) { + abort(); + return 0; + } + std::string msgid_enum_name; + if (msgname[0] == 'C' && msgname[1] == 'M') { + msgid_enum_name = "kingsomevs.CMMessageId_e"; + } else if (msgname[0] == 'S' && msgname[1] == 'M') { + msgid_enum_name = "kingsomevs.SMMessageId_e"; + } else if (msgname[0] == 'S' && msgname[1] == 'S') { + msgid_enum_name = "ss.SSMessageId_e"; + } else { + assert(false); + abort(); + return 0; + } + + auto msgid_enum = ::google::protobuf::DescriptorPool::generated_pool()->FindEnumTypeByName(msgid_enum_name); + assert(msgid_enum); + if (!msgid_enum) { + abort(); + return 0; + } + auto msgid_value = msgid_enum->FindValueByName("_" + msgname); + assert(msgid_value); + if (!msgid_value) { + abort(); + return 0; + } + return msgid_value->number(); +} + +void Net_PackMsg(unsigned short msgid, ::google::protobuf::Message& msg, std::string& out) +{ + int packlen = msg.ByteSize(); + + out.resize(sizeof(PackHead) + packlen); + char* buff = (char*)out.data(); + PackHead* head = (PackHead*)buff; + head->packlen = packlen; + head->msgid = msgid; + head->magiccode = MAGIC_CODE; + msg.SerializeToArray(buff + sizeof(PackHead), packlen); +} + +int Net_SendMsg(a8::TcpClient* tcp_client, unsigned short msgid, ::google::protobuf::Message& msg) +{ + int packlen = msg.ByteSize(); + + char* buff = (char*)malloc(sizeof(PackHead) + packlen); + PackHead* head = (PackHead*)buff; + head->packlen = packlen; + head->msgid = msgid; + head->magiccode = MAGIC_CODE; + msg.SerializeToArray(buff + sizeof(PackHead), packlen); + tcp_client->SendBuff(buff, sizeof(PackHead) + packlen); + free(buff); + return sizeof(PackHead) + packlen; +} + +int Net_SendMsg(a8::TcpListener* tcp_listener, unsigned short socket_handle, + unsigned short msgid, ::google::protobuf::Message& msg) +{ + int packlen = msg.ByteSize(); + + char* buff = (char*)malloc(sizeof(PackHead) + packlen); + PackHead* head = (PackHead*)buff; + head->packlen = packlen; + head->msgid = msgid; + head->magiccode = MAGIC_CODE; + msg.SerializeToArray(buff + sizeof(PackHead), packlen); + tcp_listener->SendClientMsg(socket_handle, buff, sizeof(PackHead) + packlen); + free(buff); + return sizeof(PackHead) + packlen; +} diff --git a/cpp/protoutils.h b/cpp/protoutils.h new file mode 100644 index 0000000..81f388f --- /dev/null +++ b/cpp/protoutils.h @@ -0,0 +1,63 @@ +#ifndef COMMON_PROTOUTILS_H +#define COMMON_PROTOUTILS_H + +//普通消息头部 +struct PackHead +{ + unsigned short packlen; + unsigned short msgid; + unsigned int magiccode; +}; + +//转发类消息头部 +struct ForwardPackHead +{ + unsigned short packlen; + unsigned short sockethandle; + unsigned short msgid; + unsigned short src_msgid; + unsigned int src_seqid; + unsigned long ip_saddr; + unsigned int sign; +}; + +class Player; +struct MsgHdr +{ + unsigned int seqid; + unsigned short msgid; + int socket_handle; + unsigned long ip_saddr; + const char* buf; + int buflen; + int offset; + Player *hum = nullptr; + const void* user_data = nullptr; +}; + +const unsigned int MAGIC_CODE = 0xAABBCCAA; + +namespace google +{ + namespace protobuf + { + class Message; + } +} + +namespace a8 +{ + class TcpClient; + class TcpListener; +} + +int Net_GetMessageId(::google::protobuf::Message& msg); + +void Net_PackMsg(unsigned short msgid, ::google::protobuf::Message& msg, std::string& out); +int Net_SendMsg(a8::TcpClient* tcp_client, unsigned short msgid, ::google::protobuf::Message& msg); +int Net_SendMsg(a8::TcpClient* tcp_client, unsigned short msgid, + const char* msgbody, int msgbody_len); +int Net_SendMsg(a8::TcpListener* tcp_tlistener, unsigned short socket_handle, + unsigned short msgid, ::google::protobuf::Message& msg); + +#endif