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