add cpp directory

This commit is contained in:
aozhiwei 2018-08-03 19:57:13 +08:00
commit c4f3714a97
4 changed files with 260 additions and 0 deletions

13
cpp/netmsghandler.cc Normal file
View File

@ -0,0 +1,13 @@
#include <a8/a8.h>
#include <google/protobuf/message.h>
#include <google/protobuf/descriptor.h>
#include "protoutils.h"
#include "netmsghandler.h"
NetMsgHandler* GetNetMsgHandler(NetMsgHandlerObject* handlers,
unsigned short msgid)
{
return msgid < MAX_MSG_ID ? handlers->handlers[msgid] : nullptr;
}

89
cpp/netmsghandler.h Normal file
View File

@ -0,0 +1,89 @@
#ifndef NETMSGHANDLER_H
#define NETMSGHANDLER_H
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/unknown_field_set.h>
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<typename InstanceType, typename MsgType>
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<typename InstanceType, typename MsgType>
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<InstanceType, MsgType>;
p->func = ptr;
p->handlerid = InstanceType::HID;
p->prototype = ::google::protobuf::MessageFactory::generated_factory()->GetPrototype(MsgType::descriptor());
msghandler->handlers[msgid] = p;
}
template<typename InstanceType>
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

95
cpp/protoutils.cc Normal file
View File

@ -0,0 +1,95 @@
#include <a8/a8.h>
#include "protoutils.h"
#include <a8/tcpclient.h>
#include <a8/tcplistener.h>
#include <google/protobuf/message.h>
#include <google/protobuf/descriptor.h>
int Net_GetMessageId(::google::protobuf::Message& msg)
{
std::string msgname;
{
std::string full_msgname = msg.GetTypeName();
std::vector<std::string> 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;
}

63
cpp/protoutils.h Normal file
View File

@ -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