Makes the autoload work without using a register function, as well as changes the networking to OpenSwoole so binary data can be send to the client
parent
6b0d439f7c
commit
fcee1f89d4
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"require": {
|
"require": {
|
||||||
"react/event-loop": "^1.5",
|
"openswoole/core": "22.1.5",
|
||||||
"react/http": "^1.9",
|
"openswoole/ide-helper": "~22.0.1"
|
||||||
"react/stream": "^1.3",
|
},
|
||||||
"react/async": "^4.2",
|
"autoload": {
|
||||||
"react/promise": "^3.1",
|
"psr-4": {
|
||||||
"react/socket": "^1.15",
|
"Emulator\\": "src/Emulator"
|
||||||
"cboden/ratchet": "^0.4.4"
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
require_once 'vendor/autoload.php';
|
require_once 'vendor/autoload.php';
|
||||||
|
|
||||||
spl_autoload_register(function(string $class) {
|
|
||||||
require_once str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
|
|
||||||
});
|
|
||||||
|
|
||||||
use Emulator\HabboEnvironment;
|
use Emulator\HabboEnvironment;
|
||||||
|
|
||||||
HabboEnvironment::getInstance()->initialize();
|
HabboEnvironment::getInstance()->initialize();
|
|
@ -7,33 +7,22 @@ use Emulator\Encoding\ByteEncoding;
|
||||||
use Emulator\Messages\Incoming\ClientMessage;
|
use Emulator\Messages\Incoming\ClientMessage;
|
||||||
use Emulator\Messages\MessageHandler;
|
use Emulator\Messages\MessageHandler;
|
||||||
use Emulator\Network\Game\Sessions\Session;
|
use Emulator\Network\Game\Sessions\Session;
|
||||||
use Override;
|
use OpenSwoole\WebSocket\Server;
|
||||||
use Ratchet\ConnectionInterface;
|
use OpenSwoole\Http\Request;
|
||||||
use Ratchet\Http\HttpServer;
|
use OpenSwoole\WebSocket\Frame;
|
||||||
use Ratchet\RFC6455\Messaging\MessageInterface;
|
|
||||||
use Ratchet\Server\IoServer;
|
|
||||||
use Ratchet\WebSocket\MessageComponentInterface;
|
|
||||||
use Ratchet\WebSocket\WsConnection;
|
|
||||||
use Ratchet\WebSocket\WsServer;
|
|
||||||
use React\EventLoop\Loop;
|
|
||||||
use React\Socket\SocketServer;
|
|
||||||
|
|
||||||
class GameNetworkServer implements MessageComponentInterface {
|
class GameNetworkServer {
|
||||||
private static ?GameNetworkServer $instance = null;
|
private static ?GameNetworkServer $instance = null;
|
||||||
private array $sessions;
|
private array $sessions;
|
||||||
|
|
||||||
public function start(int $port): void {
|
public function start(int $port): void {
|
||||||
$loop = Loop::get();
|
$server = new Server("127.0.0.1", $port);
|
||||||
|
$server->on('Start', [$this, 'onStart']);
|
||||||
$this->sessions = [];
|
$server->on('Open', [$this, 'onOpen']);
|
||||||
$socketServer = new SocketServer("127.0.0.1:{$port}", loop: $loop);
|
$server->on('Close', [$this, 'onClose']);
|
||||||
new IoServer(
|
$server->on('Disconnect', [$this, 'onDisconnect']);
|
||||||
new HttpServer(
|
$server->on('Message', [$this, 'onMessage']);
|
||||||
new WsServer($this)
|
$server->start();
|
||||||
),
|
|
||||||
$socketServer,
|
|
||||||
$loop
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getInstance(): GameNetworkServer {
|
public static function getInstance(): GameNetworkServer {
|
||||||
|
@ -44,27 +33,32 @@ class GameNetworkServer implements MessageComponentInterface {
|
||||||
return self::$instance;
|
return self::$instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Override] function onOpen(ConnectionInterface $conn): void {
|
function onStart(Server $server): void {
|
||||||
$this->sessions[$conn->resourceId] = new Session(new WsConnection($conn));
|
Logger::info("Websocket server is started at $server->host:$server->port");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Override] function onClose(ConnectionInterface $conn): void {
|
function onOpen(Server $server, Request $request): void {
|
||||||
unset($this->sessions[$conn->resourceId]);
|
$this->sessions[$request->fd] = new Session($server, $request);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Override] function onError(ConnectionInterface $conn, \Exception $e): void {
|
function onClose(Server $server, int $fd): void {
|
||||||
Logger::fatal($e->getMessage());
|
Logger::info("Connection #$fd has been closed");
|
||||||
|
unset($this->sessions[$fd]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Override] public function onMessage(ConnectionInterface $conn, MessageInterface $msg): void {
|
function onDisconnect(Server $server, int $fd): void {
|
||||||
$raw = $msg->getPayload();
|
Logger::info("Connection #$fd has disconnected");
|
||||||
$data = unpack('C*', $raw);
|
unset($this->sessions[$fd]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMessage(Server $server, Frame $frame): void {
|
||||||
|
$data = unpack('C*', $frame->data);
|
||||||
|
|
||||||
if (count($data) >= 6) {
|
if (count($data) >= 6) {
|
||||||
$length = ByteEncoding::getInt32(array_slice($data, 1, 4));
|
$length = ByteEncoding::getInt32(array_slice($data, 1, 4));
|
||||||
$packet = array_slice($data, 4, $length);
|
$packet = array_slice($data, 4, $length);
|
||||||
|
|
||||||
MessageHandler::getInstance()->handlePacket($this->sessions[$conn->resourceId], new ClientMessage($packet));
|
MessageHandler::getInstance()->handlePacket($this->sessions[$frame->fd], new ClientMessage($packet));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,15 +5,16 @@ namespace Emulator\Network\Game\Sessions;
|
||||||
use Emulator\Encoding\ByteEncoding;
|
use Emulator\Encoding\ByteEncoding;
|
||||||
use Emulator\Messages\Outgoing\IMessageComposer;
|
use Emulator\Messages\Outgoing\IMessageComposer;
|
||||||
use Emulator\Messages\Outgoing\ServerMessage;
|
use Emulator\Messages\Outgoing\ServerMessage;
|
||||||
use Ratchet\RFC6455\Messaging\Frame;
|
use OpenSwoole\Http\Request;
|
||||||
use Ratchet\RFC6455\Messaging\Message;
|
use OpenSwoole\WebSocket\Server;
|
||||||
use Ratchet\WebSocket\WsConnection;
|
|
||||||
|
|
||||||
readonly class Session {
|
readonly class Session {
|
||||||
private WsConnection $connection;
|
private Server $server;
|
||||||
|
private Request $request;
|
||||||
|
|
||||||
public function __construct(WsConnection $connection) {
|
public function __construct(Server $server, Request $request) {
|
||||||
$this->connection = $connection;
|
$this->server = $server;
|
||||||
|
$this->request = $request;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sendComposer(IMessageComposer $composer): void {
|
public function sendComposer(IMessageComposer $composer): void {
|
||||||
|
@ -21,20 +22,6 @@ readonly class Session {
|
||||||
$composer->compose($message);
|
$composer->compose($message);
|
||||||
$data = array_merge(ByteEncoding::int32ToArray(count($message->getPacket())), $message->getPacket());
|
$data = array_merge(ByteEncoding::int32ToArray(count($message->getPacket())), $message->getPacket());
|
||||||
|
|
||||||
$this->connection->send(new Frame(pack('C*', ...$data), true, Frame::OP_BINARY));
|
$this->server->push($this->request->fd, pack('C*', ...$data), Server::WEBSOCKET_OPCODE_BINARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
function encode($text) {
|
|
||||||
$b1 = 0x80 | (0x1 & 0x0f);
|
|
||||||
$length = strlen($text);
|
|
||||||
if ($length <= 125)
|
|
||||||
$header = pack('CC', $b1, $length);
|
|
||||||
elseif($length > 125 && $length < 65536)
|
|
||||||
$header = pack('CCn', $b1, 126, $length);
|
|
||||||
elseif($length >= 65536)
|
|
||||||
$header = pack('CCNN', $b1, 127, $length);
|
|
||||||
|
|
||||||
return $header.$text;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue