84 socket_set_option($socket, IPPROTO_IPV6, IPV6_V6ONLY, 1);
90 if(!@socket_bind($this->socket, $this->ip, $this->port)){
91 $error = socket_last_error($this->socket);
92 if($error === SOCKET_EADDRINUSE){
93 throw new \RuntimeException(
"Failed to bind socket: Something else is already running on $this->ip $this->port", $error);
95 throw new \RuntimeException(
"Failed to bind to $this->ip $this->port: " . trim(socket_strerror($error)), $error);
97 socket_set_nonblock($this->socket);
98 $this->logger->info(
"Running on $this->ip $this->port");
105 public function tick() : void{
106 $r = [$this->socket];
109 if(@socket_select($r, $w, $e, 0, 0) === 1){
114 $bytes = @socket_recvfrom($this->socket, $buffer, 65535, 0, $address, $port);
115 if($bytes !==
false){
116 if(isset($this->blockedIps[$address]) && $this->blockedIps[$address] > time()){
117 $this->logger->debug(
"Dropped packet from banned address $address");
120 foreach($this->rawPacketPatterns as $pattern){
121 if(preg_match($pattern, $buffer) === 1){
122 $this->network->processRawPacket($this, $address, $port, $buffer);
127 $errno = socket_last_error($this->socket);
128 if($errno === SOCKET_EWOULDBLOCK){
131 if($errno !== SOCKET_ECONNRESET){
132 $this->logger->debug(
"Failed to recv (errno $errno): " . trim(socket_strerror($errno)));
151 public function sendRawPacket(
string $address,
int $port,
string $payload) : void{
152 if(@socket_sendto($this->socket, $payload, strlen($payload), 0, $address, $port) === false){
153 $errno = socket_last_error($this->socket);
154 throw new \RuntimeException(
"Failed to send to $address $port (errno $errno): " . trim(socket_strerror($errno)), $errno);