add cpp directory
This commit is contained in:
commit
c4f3714a97
13
cpp/netmsghandler.cc
Normal file
13
cpp/netmsghandler.cc
Normal 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
89
cpp/netmsghandler.h
Normal 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
95
cpp/protoutils.cc
Normal 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
63
cpp/protoutils.h
Normal 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
|
Loading…
x
Reference in New Issue
Block a user