redtv_muqsit / simple-packet-handler
处理特定数据包(用于PMMP API 4.0.0的病毒)
dev-main
2024-09-05 20:03 UTC
This package is not auto-updated.
Last update: 2024-09-20 18:44:29 UTC
README
结束 if-elseif instanceof 的地狱。
API 文档
数据包监控器
监控数据包 - 如果您不修改事件的结果,请使用此功能。
数据包监控器在 MONITOR
优先级上注册 DataPacket(接收/发送)事件。
用例
- 从数据包中丢弃额外数据
- 调试数据包是否已发送/接收
/** @var Plugin $plugin */ $packet_monitor = SimplePacketHandler::createMonitor($plugin); $packet_monitor->monitorIncoming(function(LoginPacket $packet, NetworkSession $origin) : void{ $this->getLogger()->debug("Received LoginPacket from #" . spl_object_id($origin)); }); $packet_monitor->monitorIncoming(function(ServerSettingsResponsePacket $packet, NetworkSession $origin) : void{ $this->getLogger()->debug("Received server settings response from {$origin->getPlayer()->getName()}"); }); $packet_monitor->monitorOutgoing(function(SetActorDataPacket $packet, NetworkSession $target) : void{ $this->getLogger()->debug("Sent SetActorDataPacket to #" . spl_object_id($target)); });
上面提到的 LoginPacket
示例等同于
/** * @param DataPacketReceiveEvent $event * @priority MONITOR */ public function onDataPacketReceive(DataPacketReceiveEvent $event) : void{ $packet = $event->getPacket(); if($packet instanceof LoginPacket){ $origin = $event->getOrigin(); $this->getLogger()->debug("Received LoginPacket from #" . spl_object_id($origin)); } }
上面提到的 SetActorDataPacket
示例等同于
/** * @param DataPacketSendEvent $event * @priority MONITOR */ public function onDataPacketSend(DataPacketSendEvent $event) : void{ foreach($event->getPackets() as $packet){ if($packet instanceof SetActorDataPacket){ foreach($event->getTargets() as $target){ $this->getLogger()->debug("Sent SetActorDataPacket to #" . spl_object_id($target)); } } } }
数据包拦截器
处理数据包 - 在 MONITOR
优先级上注册 DataPacket(接收/发送)事件。
用例
- 阻止 pocketmine 处理特定的数据包
- 在 pocketmine 处理之前修改数据包
/** @var Plugin $plugin */ $packet_interceptor = SimplePacketHandler::createInterceptor($plugin); $packet_interceptor->interceptIncoming(function(AdventureSettingsPacket $packet, NetworkSession $origin) : bool{ if($packet->getFlag(AdventureSettingsPacket::FLYING)){ return false; // cancels the DataPacketReceiveEvent } return true; // do nothing }); $packet_interceptor->interceptOutgoing(function(SetTimePacket $packet, NetworkSession $target) : bool{ $custom_player = CustomPlayerManager::get($target->getPlayer()); if($custom_player->getPTime() !== $packet->time){ $target->sendDataPacket(SetTimePacket::create($custom_player->getPTime())); return false; } return true; });
上面提到的 AdventureSettingsPacket
示例等同于
/** * @param DataPacketReceiveEvent $event * @priority NORMAL */ public function onDataPacketReceive(DataPacketReceiveEvent $event) : void{ $packet = $event->getPacket(); if($packet instanceof AdventureSettingsPacket){ $origin = $event->getOrigin(); if($packet->getFlag(AdventureSettingsPacket::FLYING)){ $event->cancel(); } } }
上面提到的 SetTimePacket
示例等同于
/** * @param DataPacketSendEvent $event * @priority NORMAL */ public function onDataPacketSend(DataPacketSendEvent $event) : void{ foreach($event->getPackets() as $packet){ if($packet instanceof SetTimePacket){ $targets = $event->getTargets(); $new_targets = $targets; foreach($new_targets as $index => $target){ $custom_player = CustomPlayerManager::get($target->getPlayer()); if($custom_player->getPTime() !== $packet->time){ $target->sendDataPacket(SetTimePacket::create($custom_player->getPTime())); unset($new_targets[$index]); } } if(count($new_targets) !== count($targets)){ // Cancel the event, try sending the remaining targets the // batch of packets again. $event->cancel(); if(count($new_targets) > 0){ $new_target_players = []; foreach($new_targets as $new_target){ $new_target_players[] = $new_target->getPlayer(); } $this->getServer()->broadcastPackets($new_target_players, $event->getPackets()); } break; } } } }