RakNet 消息与函数的绑定 一个消息对应多个函数

上一篇做了RakNet 一个消息与一个函数的绑定,但实际上一个消息有时候会对应多个函数,这时候我们可以用Vector把消息处理函数存起来,然后当消息发过来的时候,循环执行所有的处理函数


在上一篇的源代码做了 添加Vector 的修改。


#include <iostream>
#include <windows.h>
#include<string>
#include <map>
#include <vector>


using namespace std;

enum GameMessage
{
	GM_LoginReturn,
	GM_getUserInfoReturn,
	GM_EverydayDrawReturn,
	GM_FriendExtendReturn
};


void getRequestLoginReturn()
{
	cout<<"Slot0 getRequestLoginReturn"<<endl;
}

void getUserInfoReturn()
{
	cout<<"Slot1 getUserInfoReturn"<<endl;
}

void getRequestEverydayDrawReturn()
{
	cout<<"Slot2 getRequestEverydayDrawReturn"<<endl;
}

void getFriendExtendOpenReturn()
{
	cout<<"Slot3 getFriendExtendOpenReturn"<<endl;
}

typedef void(*funct)();  //函数类型,代表返回值为空,参数为空的函数指针类型
map<unsigned long,vector<funct>> m_msgMap;
typedef map<unsigned long,vector<funct>> MSGMAP;


vector<funct> slotFuncVec; //一个信号对应的所有槽函数


void registerMessageHandle(unsigned long type,funct f);
void fireMessage(unsigned long type);

int main()
{
	registerMessageHandle(GM_LoginReturn,&getRequestLoginReturn);
	registerMessageHandle(GM_LoginReturn,&getRequestEverydayDrawReturn);
	registerMessageHandle(GM_LoginReturn,&getFriendExtendOpenReturn);

	registerMessageHandle(GM_getUserInfoReturn,&getUserInfoReturn);
	registerMessageHandle(GM_EverydayDrawReturn,&getRequestEverydayDrawReturn);
	registerMessageHandle(GM_FriendExtendReturn,&getFriendExtendOpenReturn);

	cout<<"注册了 "<<m_msgMap.size()<<"  条消息"<<endl;

	int msgCin;

	while(1)
	{
		cout<<"输入事件ID:";
		cin>>msgCin;

		fireMessage(msgCin);

		Sleep(10);
	}

	return 0;
}

void registerMessageHandle(unsigned long type,funct f)
{
	slotFuncVec.clear();

	MSGMAP::iterator typeIter=m_msgMap.find(type);

	if (typeIter!=m_msgMap.end())  //原来有直接在对应type的vec后面插入
	{
		typeIter->second.push_back(f);
	}
	else
	{
		slotFuncVec.push_back(f);
		m_msgMap.insert(pair<unsigned long,vector<funct> >(type,slotFuncVec));
	}
}

void fireMessage(unsigned long type)
{
	MSGMAP::iterator typeIter=m_msgMap.find(type);
	if (typeIter==m_msgMap.end()) return;

	//如果找到了这个注册消息,那么就执行这个消息对应的函数,因为一个消息可以对应多个函数,所以用vector把所有的函数存储,然后循环执行

	for (int i=0;i<typeIter->second.size();i++)
	{
		((typeIter->second)[i])();
	}
}

程序运行图:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Gophertunnel 是一个基于 Go 语言编写的 Minecraft 代理库,用于在 Minecraft 客户端和服务器之间进行中间人攻击。它允许你拦截、修改和重定向 Minecraft 客户端和服务器之间的数据包,以实现各种有趣的效果。 以下是一个示例,演示如何使用 Gophertunnel 代理 Minecraft 客户端连接到服务器: ```go package main import ( "fmt" "github.com/sandertv/gophertunnel/minecraft/login" "github.com/sandertv/gophertunnel/minecraft/protocol" "github.com/sandertv/gophertunnel/minecraft/protocol/packet" "github.com/sandertv/gophertunnel/minecraft/text" "github.com/sandertv/gophertunnel/minecraft/world" "github.com/sandertv/gophertunnel/net" ) func main() { // 创建一个 net.Listener,监听来自 Minecraft 客户端的连接请求。 listener, err := net.Listen("raknet", "localhost:19132") if err != nil { panic(err) } defer listener.Close() // 监听连接请求,打印客户端的 IP 地址。 fmt.Println("Listening on", listener.Addr()) for { conn, err := listener.Accept() if err != nil { panic(err) } fmt.Println("Accepted connection from", conn.RemoteAddr()) // 启动一个 Minecraft 登录会话,以验证客户端的身份。 clientData := &login.ClientData{} serverData := &login.ServerData{} serverData.CurrentProtocol = protocol.MinecraftBedrock_1_16_201 serverData.GameVersion = "1.16.201" session := login.NewSession(conn, clientData, serverData) session.Start() // 如果验证成功,接受客户端和服务器之间的数据包。 go func() { for { pk, err := session.Conn.ReadPacket() if err != nil { panic(err) } handlePacket(pk) } }() // 发送一个 MOTD 描述信息到客户端。 pk := &packet.Text{ Type: text.TypeRaw, Text: "Welcome to my Minecraft server!", } if err := session.Conn.WritePacket(pk); err != nil { panic(err) } // 加载一个新的 Minecraft 世界,并将客户端连接到该世界。 world, err := world.NewWorld() if err != nil { panic(err) } if err := session.Conn.WritePacket(&packet.StartGame{ EntityUniqueID: 1, PlayerGameMode: protocol.GameModeSurvival, Dimension: world.Dimension, Difficulty: world.Difficulty, SpawnVector: world.Spawn, }); err != nil { panic(err) } } } func handlePacket(pk packet.Packet) { // 处理客户端和服务器之间传输的数据包。 switch pk := pk.(type) { case *packet.MovePlayer: fmt.Println("Player moved:", pk.Position) case *packet.Text: fmt.Println("Received text message:", pk.Text) } } ``` 在此示例中,我们创建了一个 Minecraft 服务器代理,监听来自 Minecraft 客户端的连接请求,并在客户端连接时创建了一个新的 Minecraft 世界。我们还向客户端发送了一个简单的欢迎信息,并处理了客户端和服务器之间传输的数据包,以进行一些基本的操作(例如,打印玩家移动事件和接收文本消息)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值