Browse Source

implement rooms navigation

main
ghost 7 months ago
parent
commit
1d71d667bc
  1. 23
      config/example.json
  2. 294
      src/Server/Ratchet.php

23
config/example.json

@ -11,7 +11,11 @@
}, },
"wallet": "wallet":
{ {
"namespace":"", "namespace":
{
"whitelist":[],
"blacklist":[]
},
"account":null "account":null
}, },
"event": "event":
@ -60,7 +64,7 @@
"debug": "debug":
{ {
"enabled":true, "enabled":true,
"template":"[{time}] [init] listen on {host}:{port} balance: {keva}" "template":"[{time}] [init] listen on {host}:{port} balance: {keva} allowed: {room}"
} }
}, },
"open": "open":
@ -84,13 +88,26 @@
{ {
"success": "success":
[ [
"\u001b[34mWell, enter your message (dot to commit)\u001b[0m" "\u001b[34mWell, select room number\u001b[0m",
"\u001b[35m{room:list}\u001b[0m"
], ],
"failure": "failure":
[ [
"\u001b[31mIncorrect captcha code, try again later!\u001b[0m" "\u001b[31mIncorrect captcha code, try again later!\u001b[0m"
] ]
}, },
"room":
{
"success":
[
"\u001b[34mRoom changed to \u001b[35m{room}\u001b[0m",
"\u001b[34mEnter your message (dot to commit)\u001b[0m"
],
"failure":
[
"\u001b[31mRequested room number not found, try again!\u001b[0m"
]
},
"submit": "submit":
{ {
"success": "success":

294
src/Server/Ratchet.php

@ -10,6 +10,8 @@ class Ratchet implements MessageComponentInterface
private object $_config; private object $_config;
private array $_namespaces;
public function __construct( public function __construct(
object $config object $config
) { ) {
@ -31,6 +33,50 @@ class Ratchet implements MessageComponentInterface
throw new \Exception(); // @TODO throw new \Exception(); // @TODO
} }
// Init allowed chat rooms registry
if ($namespaces = $this->_kevacoin->kevaListNamespaces())
{
$i = 1; foreach ((array) $namespaces as $namespace)
{
// Skip system namespaces
if (str_starts_with($namespace['displayName'], '_'))
{
continue;
}
// Skip blacklist
if (in_array($namespace['namespaceId'], $this->_config->kevacoin->wallet->namespace->blacklist))
{
continue;
}
// Check whitelist on contain records
if (count($this->_config->kevacoin->wallet->namespace->whitelist) &&
!in_array($namespace['namespaceId'], $this->_config->kevacoin->wallet->namespace->whitelist))
{
continue;
}
// Append room to the namespace registry
$this->_namespaces[$i++] = [
'hash' => $namespace['namespaceId'],
'name' => $namespace['displayName']
];
}
// Sort rooms by name ASC
array_multisort(
array_column(
$this->_namespaces,
'name'
),
SORT_ASC,
SORT_STRING | SORT_NATURAL | SORT_FLAG_CASE
);
}
else throw new \Exception(); // @TODO
// Dump event on enabled // Dump event on enabled
if ($this->_config->nps->event->init->debug->enabled) if ($this->_config->nps->event->init->debug->enabled)
{ {
@ -40,7 +86,8 @@ class Ratchet implements MessageComponentInterface
'{time}', '{time}',
'{host}', '{host}',
'{port}', '{port}',
'{keva}' '{keva}',
'{room}'
], ],
[ [
(string) date('c'), (string) date('c'),
@ -48,6 +95,10 @@ class Ratchet implements MessageComponentInterface
(string) $this->_config->nps->server->port, (string) $this->_config->nps->server->port,
(float) $this->_kevacoin->getBalance( (float) $this->_kevacoin->getBalance(
$this->_config->kevacoin->wallet->account $this->_config->kevacoin->wallet->account
),
(string) print_r(
$this->_namespaces,
true
) )
], ],
$this->_config->nps->event->init->debug->template $this->_config->nps->event->init->debug->template
@ -104,6 +155,9 @@ class Ratchet implements MessageComponentInterface
// Init connection confirmed // Init connection confirmed
$connection->confirmed = false; $connection->confirmed = false;
// Init connection room
$connection->namespace = null;
// Init connection counter // Init connection counter
$connection->count = 0; $connection->count = 0;
@ -180,140 +234,215 @@ class Ratchet implements MessageComponentInterface
// Connection confirmed // Connection confirmed
if ($connection->confirmed) if ($connection->confirmed)
{ {
// Check message commit by dot // Room selected, begin message compose
if ($request == '.') if ($connection->namespace)
{ {
// Check message not empty // Check message commit by dot
if (empty(trim($connection->message))) if ($request == '.')
{
$connection->send(
implode(
PHP_EOL,
$config->response->submit->failure->empty
) . PHP_EOL
);
}
// Max length already checked on input, begin message save
else
{ {
// Save massage to KevaCoin blockchain // Check message not empty
if ($txid = $this->_kevacoin->kevaPut($this->_config->kevacoin->wallet->namespace, time(), $connection->message)) if (empty(trim($connection->message)))
{ {
// Return success response
$connection->send( $connection->send(
str_ireplace( implode(
[ PHP_EOL,
'{name}', $config->response->submit->failure->empty
'{txid}' ) . PHP_EOL
],
[
(string) $this->_config->kevacoin->wallet->namespace,
(string) $txid
],
implode(
PHP_EOL,
$config->response->submit->success
) . PHP_EOL
)
); );
}
// Print transaction debug info on enabled // Max length already checked on input, begin message save
if ($this->_config->kevacoin->event->put->debug->enabled) else
{
// Save massage to KevaCoin blockchain
if ($txid = $this->_kevacoin->kevaPut($connection->namespace, time(), $connection->message))
{ {
print( // Return success response
$connection->send(
str_ireplace( str_ireplace(
[ [
'{time}',
'{host}',
'{crid}',
'{name}', '{name}',
'{txid}', '{txid}'
'{keva}'
], ],
[ [
(string) date('c'), (string) $connection->namespace,
(string) $connection->remoteAddress, (string) $txid
(string) $connection->resourceId,
(string) $this->_config->kevacoin->wallet->namespace,
(string) $txid,
(string) $this->_kevacoin->getBalance(
$this->_config->kevacoin->wallet->account
)
], ],
$this->_config->kevacoin->event->put->debug->template implode(
PHP_EOL,
$config->response->submit->success
) . PHP_EOL
)
);
// Print transaction debug info on enabled
if ($this->_config->kevacoin->event->put->debug->enabled)
{
print(
str_ireplace(
[
'{time}',
'{host}',
'{crid}',
'{name}',
'{txid}',
'{keva}'
],
[
(string) date('c'),
(string) $connection->remoteAddress,
(string) $connection->resourceId,
(string) $connection->namespace,
(string) $txid,
(string) $this->_kevacoin->getBalance(
$this->_config->kevacoin->wallet->account
)
],
$this->_config->kevacoin->event->put->debug->template
) . PHP_EOL
);
}
}
// Could not receive transaction, something went wrong
else
{
$connection->send(
implode(
PHP_EOL,
$config->response->submit->failure->internal
) . PHP_EOL ) . PHP_EOL
); );
} }
} }
// Could not receive transaction, something went wrong // Close connection at this point
else $connection->close();
{
$connection->send(
implode(
PHP_EOL,
$config->response->submit->failure->internal
) . PHP_EOL
);
}
} }
// Close connection at this point // Complete message by new line sent
$connection->close(); $connection->message .= $request . PHP_EOL;
}
// Complete message by new line sent // Check message encoding valid
$connection->message .= $request . PHP_EOL; if (!mb_check_encoding($connection->message, 'UTF-8'))
{
$connection->send(
implode(
PHP_EOL,
$config->response->submit->failure->encoding
) . PHP_EOL
);
// Check message encoding valid $connection->close();
if (!mb_check_encoding($connection->message, 'UTF-8')) }
// Check total message length limit allowed by KevaCoin protocol
if (mb_strlen($connection->message) > 3074)
{
$connection->send(
implode(
PHP_EOL,
$config->response->submit->failure->length
) . PHP_EOL
);
$connection->close();
}
}
// Room not selected yet and number given match registry
else if (isset($this->_namespaces[$request]))
{ {
// Update connection namespace
$connection->namespace = $this->_namespaces[$request]['hash'];
// Send room selection request
$connection->send( $connection->send(
implode( str_ireplace(
PHP_EOL, [
$config->response->submit->failure->encoding '{room}'
) . PHP_EOL ],
[
str_replace( // filter possible meta mask in the room names
'%',
'%%',
$this->_namespaces[$request]['name']
)
],
implode(
PHP_EOL,
$config->response->room->success
) . PHP_EOL
)
); );
$connection->close();
} }
// Check total message length limit allowed by KevaCoin protocol // Room number not found in registry
if (mb_strlen($connection->message) > 3074) else
{ {
// Reset connection room anyway
$connection->namespace = null;
// Send fail response
$connection->send( $connection->send(
implode( implode(
PHP_EOL, PHP_EOL,
$config->response->submit->failure->length $config->response->room->failure
) . PHP_EOL ) . PHP_EOL
); );
$connection->close(); // Keep connection alive for new attempt..
} }
} }
// Captcha request // Captcha confirmation code expected
else else
{ {
// Request match captcha // Request match captcha
if ($request == $connection->captcha) if ($request == $connection->captcha)
{ {
// Set connection confirmed
$connection->confirmed = true; $connection->confirmed = true;
// Build room list
$rooms = [];
foreach ($this->_namespaces as $number => $namespace)
{
$rooms[] = sprintf(
'[%d] %s',
$number,
$namespace['name']
);
}
// Send room selection request
$connection->send( $connection->send(
implode( str_ireplace(
PHP_EOL, [
$config->response->captcha->success '{room:list}'
) . PHP_EOL ],
[
implode(
PHP_EOL,
$rooms
)
],
implode(
PHP_EOL,
$config->response->captcha->success
) . PHP_EOL
)
); );
} }
// Captcha request invalid // Captcha request invalid
else else
{ {
// Reset confirmed status
$connection->confirmed = false; $connection->confirmed = false;
// Send fail response
$connection->send( $connection->send(
implode( implode(
PHP_EOL, PHP_EOL,
@ -321,6 +450,7 @@ class Ratchet implements MessageComponentInterface
) . PHP_EOL ) . PHP_EOL
); );
// Drop connection to prevent brute force
$connection->close(); $connection->close();
} }
} }

Loading…
Cancel
Save