refactor: move navbar and footer to layout.tsx

This commit is contained in:
Konstantin Zhigaylo 2025-07-01 15:40:10 +03:00
parent c52e971b36
commit 66b780eaad
No known key found for this signature in database
GPG Key ID: DD1C2780F0E05B5C
8 changed files with 394 additions and 449 deletions

2
.gitignore vendored
View File

@ -39,3 +39,5 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
/.idea

View File

@ -1,6 +1,8 @@
import type { Metadata } from "next";
import { Geist, Rokkitt } from "next/font/google";
import "./globals.css";
import NavBar from "@/components/NavBar";
import Footer from "@/components/Footer";
const geistSans = Geist({
variable: "--font-geist",
@ -25,9 +27,11 @@ export default function RootLayout({
return (
<html lang="en">
<body
className={`${geistSans.variable} ${rokkitt.variable} bg-stone-900 font-geist antialiased`}
className={`${geistSans.variable} ${rokkitt.variable} flex flex-col gap-4 bg-stone-900 font-geist antialiased max-w-[700px] mx-auto p-4 pt-15`}
>
<NavBar />
{children}
<Footer />
</body>
</html>
);

View File

@ -1,25 +1,17 @@
import NavBar from "@/components/NavBar";
import Footer from "@/components/Footer";
import Text from "@/components/blocks/Text";
export default function Home() {
return (
<div className={"bg-stone-900 min-h-screen font-geist"}>
<main
className={"max-w-[700px] pt-15 flex flex-col gap-4 mx-auto w-full p-4"}
>
<NavBar />
<Text>
Welcome to an unofficial webpage about the Real Address Chat protocol.
Here you can find clients, servers, and documentation on how to use
RAC and its successor, WRAC.
</Text>
<Text>
Want to add your project to Racinfo? Make a pull request on our
official GitHub repository, and well review it.
</Text>
<Footer />
</main>
</div>
<main className={"flex flex-col gap-4 mx-auto w-full"}>
<Text>
Welcome to an unofficial webpage about the Real Address Chat protocol.
Here you can find clients, servers, and documentation on how to use RAC
and its successor, WRAC.
</Text>
<Text>
Want to add your project to Racinfo? Make a pull request on our official
GitHub repository, and well review it.
</Text>
</main>
);
}

View File

@ -43,13 +43,6 @@ export default function Projects() {
description: "Coming Soon™",
tags: ["Unreleased", "WRAC", "RAC", "v2"],
},
{
name: "oWRAC",
authorId: "pansangg",
projectGit: "https://github.com/pansangg/oWRAC",
description: "An online WRAC client (works in web)",
tags: ["Unreleased", "WRAC", "v2"],
},
{
name: "clRAC",
externalDownload: true,
@ -116,61 +109,55 @@ export default function Projects() {
];
return (
<div className={"bg-stone-900 min-h-screen font-geist"}>
<main
className={"max-w-[700px] pt-15 flex flex-col gap-4 mx-auto w-full p-4"}
>
<NavBar />
<PageTitle id={"projects"}>Projects</PageTitle>
<Text>
This is a curated list of projects that is related to RAC protocol.
There is a client and server implementations of RAC. Note that some
projects are not available on Git services and should be downloaded
from external sources. They are marked with
<InlineCode>external@</InlineCode> text at the beginning of the author
ID. If you want to add your project to this list, please make an issue
on our GitHub repository.
</Text>
<Title id={"clients"}>Clients</Title>
<Text>
Here is a grid of all available client for RAC protocol with their
respective repository link.
</Text>
<div className={"grid grid-cols-1 md:grid-cols-2 gap-4 w-full"}>
{clients.map((client) => (
<ProjectCard
key={client.name}
name={client.name}
externalDownload={client.externalDownload || undefined}
externalLink={client.externalLink || undefined}
authorId={client.authorId}
projectGit={client.projectGit}
description={client.description}
tags={client.tags}
/>
))}
</div>
<Title id={"servers"}>Servers</Title>
<Text>
And here are the servers implementation! You can choose whatever you
want and setup your own RAC server.
</Text>
<div className={"grid grid-cols-1 md:grid-cols-2 gap-4 w-full"}>
{servers.map((server) => (
<ProjectCard
key={server.name}
name={server.name}
externalDownload={server.externalDownload}
externalLink={server.externalLink}
authorId={server.authorId}
projectGit={server.projectGit}
description={server.description}
tags={server.tags}
/>
))}
</div>
<Footer />
</main>
</div>
<main className={"flex flex-col gap-4 w-full"}>
<PageTitle id={"projects"}>Projects</PageTitle>
<Text>
This is a curated list of projects that is related to RAC protocol.
There is a client and server implementations of RAC. Note that some
projects are not available on Git services and should be downloaded from
external sources. They are marked with
<InlineCode>external@</InlineCode> text at the beginning of the author
ID. If you want to add your project to this list, please make an issue
on our GitHub repository.
</Text>
<Title id={"clients"}>Clients</Title>
<Text>
Here is a grid of all available client for RAC protocol with their
respective repository link.
</Text>
<div className={"grid grid-cols-1 md:grid-cols-2 gap-4 w-full"}>
{clients.map((client) => (
<ProjectCard
key={client.name}
name={client.name}
externalDownload={client.externalDownload || undefined}
externalLink={client.externalLink || undefined}
authorId={client.authorId}
projectGit={client.projectGit}
description={client.description}
tags={client.tags}
/>
))}
</div>
<Title id={"servers"}>Servers</Title>
<Text>
And here are the servers implementation! You can choose whatever you
want and setup your own RAC server.
</Text>
<div className={"grid grid-cols-1 md:grid-cols-2 gap-4 w-full"}>
{servers.map((server) => (
<ProjectCard
key={server.name}
name={server.name}
externalDownload={server.externalDownload}
externalLink={server.externalLink}
authorId={server.authorId}
projectGit={server.projectGit}
description={server.description}
tags={server.tags}
/>
))}
</div>
</main>
);
}

View File

@ -1,81 +1,73 @@
import NavBar from "@/components/NavBar";
import Footer from "@/components/Footer";
import Link from "next/link";
import Link from "next/link";
import Text from "@/components/blocks/Text";
import PageTitle from "@/components/blocks/PageTitle";
import Title from "@/components/blocks/Title";
export default function Protocol() {
return (
<div className={"bg-stone-900 min-h-screen font-geist"}>
<main
className={"max-w-[700px] pt-15 flex flex-col gap-4 mx-auto w-full p-4"}
>
<NavBar />
<PageTitle id={"protocol"}>Protocol</PageTitle>
<Text>
Real Address Chat is a protocol based on TCP intended for chatting,
like IRC. It was supposed to be an IRC killer, but in reality, its
implementation is poor. Theres also a community-made successor called
WRAC. Its basically the same as RAC, but it uses WebSockets instead
of TCP for connections.
</Text>
<Text>
If you want to experiment with or implement RAC in your client or
server, use the documentation below to understand how it works.
</Text>
<Title id={"articles"}>Articles</Title>
<Text>Click on article down below that you want to read.</Text>
<div className={"flex flex-col gap-2"}>
<Link
href={"/protocol/rac"}
className={
"flex flex-col bg-stone-900 border border-stone-800 p-4 transition-all duration-200 hover:border-neutral-600 hover:bg-stone-800 rounded-lg"
}
>
<h1 className={"text-stone-300 font-rokkitt text-2xl font-bold"}>
Real Address Chat Protocol
</h1>
<p className={"text-stone-500"}>
This article explains the Real Address Chat protocol and how the
client and server interact with each other using it.
</p>
<small className={"text-stone-600"}>Curated by @kostya-zero</small>
</Link>
<Link
href={"/protocol/wrac"}
className={
"flex flex-col bg-stone-900 border border-stone-800 p-4 transition-all duration-200 hover:border-neutral-600 hover:bg-stone-800 rounded-lg"
}
>
<h1 className={"text-stone-300 font-rokkitt text-2xl font-bold"}>
WebSocket Real Address Chat Protocol
</h1>
<p className={"text-stone-500"}>
WRAC is a WebSocket-based implementation of the RAC protocol, made
by the community. It works the same as RAC but includes some
additions.
</p>
<small className={"text-stone-600"}>Curated by @kostya-zero</small>
</Link>
<Link
href={"/protocol/user-agents"}
className={
"flex flex-col bg-stone-900 border border-stone-800 p-4 transition-all duration-200 hover:border-neutral-600 hover:bg-stone-800 rounded-lg"
}
>
<h1 className={"text-stone-300 font-rokkitt text-2xl font-bold"}>
User Agents
</h1>
<p className={"text-stone-500"}>
A community-made solution to identify clients by a unique symbol
in front of their username.
</p>
<small className={"text-stone-600"}>Curated by @kostya-zero</small>
</Link>
</div>
<Footer />
</main>
</div>
<main className={"flex flex-col gap-4 w-full"}>
<PageTitle id={"protocol"}>Protocol</PageTitle>
<Text>
Real Address Chat is a protocol based on TCP intended for chatting, like
IRC. It was supposed to be an IRC killer, but in reality, its
implementation is poor. Theres also a community-made successor called
WRAC. Its basically the same as RAC, but it uses WebSockets instead of
TCP for connections.
</Text>
<Text>
If you want to experiment with or implement RAC in your client or
server, use the documentation below to understand how it works.
</Text>
<Title id={"articles"}>Articles</Title>
<Text>Click on article down below that you want to read.</Text>
<div className={"flex flex-col gap-2"}>
<Link
href={"/protocol/rac"}
className={
"flex flex-col bg-stone-900 border border-stone-800 p-4 transition-all duration-200 hover:border-neutral-600 hover:bg-stone-800 rounded-lg"
}
>
<h1 className={"text-stone-300 font-rokkitt text-2xl font-bold"}>
Real Address Chat Protocol
</h1>
<p className={"text-stone-500"}>
This article explains the Real Address Chat protocol and how the
client and server interact with each other using it.
</p>
<small className={"text-stone-600"}>Curated by @kostya-zero</small>
</Link>
<Link
href={"/protocol/wrac"}
className={
"flex flex-col bg-stone-900 border border-stone-800 p-4 transition-all duration-200 hover:border-neutral-600 hover:bg-stone-800 rounded-lg"
}
>
<h1 className={"text-stone-300 font-rokkitt text-2xl font-bold"}>
WebSocket Real Address Chat Protocol
</h1>
<p className={"text-stone-500"}>
WRAC is a WebSocket-based implementation of the RAC protocol, made
by the community. It works the same as RAC but includes some
additions.
</p>
<small className={"text-stone-600"}>Curated by @kostya-zero</small>
</Link>
<Link
href={"/protocol/user-agents"}
className={
"flex flex-col bg-stone-900 border border-stone-800 p-4 transition-all duration-200 hover:border-neutral-600 hover:bg-stone-800 rounded-lg"
}
>
<h1 className={"text-stone-300 font-rokkitt text-2xl font-bold"}>
User Agents
</h1>
<p className={"text-stone-500"}>
A community-made solution to identify clients by a unique symbol in
front of their username.
</p>
<small className={"text-stone-600"}>Curated by @kostya-zero</small>
</Link>
</div>
</main>
);
}

View File

@ -1,6 +1,4 @@
import NavBar from "@/components/NavBar";
import Footer from "@/components/Footer";
import { ArrowLeft } from "lucide-react";
import { ArrowLeft } from "lucide-react";
import Link from "next/link";
import {
Table,
@ -18,189 +16,179 @@ import Code from "@/components/blocks/Code";
export default function Rac() {
return (
<div className={"bg-stone-900 min-h-screen font-geist"}>
<main
className={"max-w-[700px] pt-15 flex flex-col gap-4 mx-auto w-full p-4"}
<main className={"flex flex-col gap-4 w-full"}>
<Link
href={"/protocol"}
className={
"text-stone-500 flex flex-row items-center transition duration-200 hover:text-stone-50 gap-2"
}
>
<NavBar />
<Link
href={"/protocol"}
className={
"text-stone-500 flex flex-row items-center transition duration-200 hover:text-stone-50 gap-2"
}
>
<ArrowLeft size={16} /> Go Back
</Link>
<PageTitle id={"real-address-chat-protocol"}>
Real Address Chat Protocol
</PageTitle>
<Text>
As mentioned earlier, RAC is a TCP-based protocol, so the server and
client communicate by sending TCP packets to each other. The
implementation is pretty simple, so dont worry.
</Text>
<Text>
All RAC servers use port <InlineCode>42666</InlineCode> by default,
but servers that implement RACS (Real Address Chat Secure) use port{" "}
<InlineCode>42667</InlineCode>.
</Text>
<Text>
Keep in mind that the RAC server closes the connection after each
message sent from the client. In some cases, it might receive two
packets, but it will still close the connection.
</Text>
<Title id={"receiving-messages"}>Receiving messages</Title>
<Text>
Receiving messages from the server is implemented in an unusual way.
There are two ways to receive messages from the server.
</Text>
<Text>
But before you try to receive new messages, you need to get the total
size of all messages. The messages are stored on the server in a
single file, and to get new messages, you should send an offset.
</Text>
<Text>
To receive the current size of the messages on the server, you need to
send a <InlineCode>0x00</InlineCode> byte to the server. In response,
the server will return the current size of the messages. Now, lets
begin receiving those messages.
</Text>
<Text>
The first way is to receive all messages stored on the server. The
client should send a <InlineCode>0x00</InlineCode> byte and then, in
the same stream, send a <InlineCode>0x01</InlineCode> byte to the
server. The server will respond with all messages, separated by{" "}
<InlineCode>\n</InlineCode>.
</Text>
<Text>
The second way is to get messages in chunks. Again, the client sends a{" "}
<InlineCode>0x00</InlineCode> byte and then sends a{" "}
<InlineCode>0x02</InlineCode> byte, along with the size of the
messages it wants to receive. The number of messages to receive is
calculated using this formula:
</Text>
<Code>new_received_size - last_known_size</Code>
<Text>
The server will send messages matching the requested size, separated
by <InlineCode>\n</InlineCode>.
</Text>
<Title id={"sending-messages"}>Sending messages</Title>
<Text>
Sending messages in RAC is implemented simply, but with some
interesting details. The server doesnt identify clients or users, so
clients have to handle that themselves. This means the client must
send the user agent, username, and message all in one packet. For
example:
</Text>
<Code>{"▲<zero> Hello, world!"}</Code>
<Text>
Did you notice the <InlineCode></InlineCode> symbol? This is called a
User Agent. In this example, the message was sent by the Tower client,
because <InlineCode></InlineCode> is its respective user agent. As
mentioned earlier, the server itself cannot identify clients, so
clients have to identify each other using these user agents.
</Text>
<Text>
Also, note that <InlineCode>zero</InlineCode> is wrapped inside{" "}
<InlineCode>{"<>"}</InlineCode>. This approach makes parsing messages
easier with regex. Learn more about user agents and how to create your
own in the user agents article.
</Text>
<Text>
Note that the server should store the IP address with each sent
message. However, messages sent by clients in authorized mode should
be ignored for this. This idea, introduced by Sugoma, means that
clients shouldnt be anonymous unless theyre authorized. Still, most
clients ignore the IP address and dont display it.
</Text>
<Text>
Back to sending messages: To send a message to the server, the client
should send a <InlineCode>0x01</InlineCode> byte, followed by the
message in the same packetnot separately. After that, you wont
receive anything from the server, even if theres an error. So your
final message should look like this:
</Text>
<Code>{"<user> Hello, everyone!"}</Code>
<Text>
Also, server that are implements RAC v2 allows to send messages in
authorized mode. To send message in authorized mode, you need to send{" "}
<InlineCode>0x02</InlineCode> and after that, separating by{" "}
<InlineCode>\n</InlineCode>, send user&apos;s user name, password and
message (<b>do not</b> include <InlineCode>\n</InlineCode> in the
end).
</Text>
<Text>
If the message was sent successfully, the server wont send any
response. If not, the server will send a <InlineCode>0x01</InlineCode>{" "}
byte if the user doesnt exist, and a <InlineCode>0x02</InlineCode>{" "}
byte if the password is incorrect.
</Text>
<Title id={"authorization"}>Authorization</Title>
<Text>
Authorization is only available on servers that implement the RAC v2
protocol, which adds an authorization system. This feature was added
by Sugoma for people who dont want to expose their IP address to
everyone.
</Text>
<Text>
Before sending messages in authorized mode, you need to register a
user on the server. To do this, the client should send a{" "}
<InlineCode>0x03</InlineCode> byte and, just like when sending
messages, include the username and password separated by{" "}
<InlineCode>\n</InlineCode>. If the user is created, the client will
receive nothing in response. If the user already exists, the server
will respond with a <InlineCode>0x01</InlineCode> byte.
</Text>
<Title id={"tls-connection"}>TLS Connection</Title>
<Text>
You can wrap your connection with TLS encryption. Theres nothing
special about it.
</Text>
<Title id={"special-packets"}>Special Packets</Title>
<Text>
Some servers can implement special packets, but most of the time they
dont add much functionality.
</Text>
<Text>
One of them is the <InlineCode>0x69</InlineCode> byte. You can send
this byte to the server to get technical information about it. For
example, after sending this byte, you might receive these bytes in
response:
</Text>
<Table>
<TableHeader>
<TableRow>
<TableHead className={"w-[150px]"}>Byte</TableHead>
<TableHead>Meaning</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell className={"font-semibold"}>
<InlineCode>0x01</InlineCode>
</TableCell>
<TableCell>The server supports RAC v1.0</TableCell>
</TableRow>
<TableRow>
<TableCell className={"font-semibold"}>
<InlineCode>0x02</InlineCode>
</TableCell>
<TableCell>The server supports RAC v1.99</TableCell>
</TableRow>
<TableRow>
<TableCell className={"font-semibold"}>
<InlineCode>0x03</InlineCode>
</TableCell>
<TableCell>The server supports RAC v2.0</TableCell>
</TableRow>
</TableBody>
</Table>
<Text>
Also, right after this byte, the server will send information about
itself, such as the server software name and its version.
</Text>
<Footer />
</main>
</div>
<ArrowLeft size={16} /> Go Back
</Link>
<PageTitle id={"real-address-chat-protocol"}>
Real Address Chat Protocol
</PageTitle>
<Text>
As mentioned earlier, RAC is a TCP-based protocol, so the server and
client communicate by sending TCP packets to each other. The
implementation is pretty simple, so dont worry.
</Text>
<Text>
All RAC servers use port <InlineCode>42666</InlineCode> by default, but
servers that implement RACS (Real Address Chat Secure) use port{" "}
<InlineCode>42667</InlineCode>.
</Text>
<Text>
Keep in mind that the RAC server closes the connection after each
message sent from the client. In some cases, it might receive two
packets, but it will still close the connection.
</Text>
<Title id={"receiving-messages"}>Receiving messages</Title>
<Text>
Receiving messages from the server is implemented in an unusual way.
There are two ways to receive messages from the server.
</Text>
<Text>
But before you try to receive new messages, you need to get the total
size of all messages. The messages are stored on the server in a single
file, and to get new messages, you should send an offset.
</Text>
<Text>
To receive the current size of the messages on the server, you need to
send a <InlineCode>0x00</InlineCode> byte to the server. In response,
the server will return the current size of the messages. Now, lets
begin receiving those messages.
</Text>
<Text>
The first way is to receive all messages stored on the server. The
client should send a <InlineCode>0x00</InlineCode> byte and then, in the
same stream, send a <InlineCode>0x01</InlineCode> byte to the server.
The server will respond with all messages, separated by{" "}
<InlineCode>\n</InlineCode>.
</Text>
<Text>
The second way is to get messages in chunks. Again, the client sends a{" "}
<InlineCode>0x00</InlineCode> byte and then sends a{" "}
<InlineCode>0x02</InlineCode> byte, along with the size of the messages
it wants to receive. The number of messages to receive is calculated
using this formula:
</Text>
<Code>new_received_size - last_known_size</Code>
<Text>
The server will send messages matching the requested size, separated by{" "}
<InlineCode>\n</InlineCode>.
</Text>
<Title id={"sending-messages"}>Sending messages</Title>
<Text>
Sending messages in RAC is implemented simply, but with some interesting
details. The server doesnt identify clients or users, so clients have
to handle that themselves. This means the client must send the user
agent, username, and message all in one packet. For example:
</Text>
<Code>{"▲<zero> Hello, world!"}</Code>
<Text>
Did you notice the <InlineCode></InlineCode> symbol? This is called a
User Agent. In this example, the message was sent by the Tower client,
because <InlineCode></InlineCode> is its respective user agent. As
mentioned earlier, the server itself cannot identify clients, so clients
have to identify each other using these user agents.
</Text>
<Text>
Also, note that <InlineCode>zero</InlineCode> is wrapped inside{" "}
<InlineCode>{"<>"}</InlineCode>. This approach makes parsing messages
easier with regex. Learn more about user agents and how to create your
own in the user agents article.
</Text>
<Text>
Note that the server should store the IP address with each sent message.
However, messages sent by clients in authorized mode should be ignored
for this. This idea, introduced by Sugoma, means that clients shouldnt
be anonymous unless theyre authorized. Still, most clients ignore the
IP address and dont display it.
</Text>
<Text>
Back to sending messages: To send a message to the server, the client
should send a <InlineCode>0x01</InlineCode> byte, followed by the
message in the same packetnot separately. After that, you wont receive
anything from the server, even if theres an error. So your final
message should look like this:
</Text>
<Code>{"<user> Hello, everyone!"}</Code>
<Text>
Also, server that are implements RAC v2 allows to send messages in
authorized mode. To send message in authorized mode, you need to send{" "}
<InlineCode>0x02</InlineCode> and after that, separating by{" "}
<InlineCode>\n</InlineCode>, send user&apos;s user name, password and
message (<b>do not</b> include <InlineCode>\n</InlineCode> in the end).
</Text>
<Text>
If the message was sent successfully, the server wont send any
response. If not, the server will send a <InlineCode>0x01</InlineCode>{" "}
byte if the user doesnt exist, and a <InlineCode>0x02</InlineCode> byte
if the password is incorrect.
</Text>
<Title id={"authorization"}>Authorization</Title>
<Text>
Authorization is only available on servers that implement the RAC v2
protocol, which adds an authorization system. This feature was added by
Sugoma for people who dont want to expose their IP address to everyone.
</Text>
<Text>
Before sending messages in authorized mode, you need to register a user
on the server. To do this, the client should send a{" "}
<InlineCode>0x03</InlineCode> byte and, just like when sending messages,
include the username and password separated by{" "}
<InlineCode>\n</InlineCode>. If the user is created, the client will
receive nothing in response. If the user already exists, the server will
respond with a <InlineCode>0x01</InlineCode> byte.
</Text>
<Title id={"tls-connection"}>TLS Connection</Title>
<Text>
You can wrap your connection with TLS encryption. Theres nothing
special about it.
</Text>
<Title id={"special-packets"}>Special Packets</Title>
<Text>
Some servers can implement special packets, but most of the time they
dont add much functionality.
</Text>
<Text>
One of them is the <InlineCode>0x69</InlineCode> byte. You can send this
byte to the server to get technical information about it. For example,
after sending this byte, you might receive these bytes in response:
</Text>
<Table>
<TableHeader>
<TableRow>
<TableHead className={"w-[150px]"}>Byte</TableHead>
<TableHead>Meaning</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell className={"font-semibold"}>
<InlineCode>0x01</InlineCode>
</TableCell>
<TableCell>The server supports RAC v1.0</TableCell>
</TableRow>
<TableRow>
<TableCell className={"font-semibold"}>
<InlineCode>0x02</InlineCode>
</TableCell>
<TableCell>The server supports RAC v1.99</TableCell>
</TableRow>
<TableRow>
<TableCell className={"font-semibold"}>
<InlineCode>0x03</InlineCode>
</TableCell>
<TableCell>The server supports RAC v2.0</TableCell>
</TableRow>
</TableBody>
</Table>
<Text>
Also, right after this byte, the server will send information about
itself, such as the server software name and its version.
</Text>
</main>
);
}

View File

@ -1,6 +1,4 @@
import NavBar from "@/components/NavBar";
import Footer from "@/components/Footer";
import { ArrowLeft } from "lucide-react";
import { ArrowLeft } from "lucide-react";
import Link from "next/link";
import {
Table,
@ -60,69 +58,61 @@ export default function Wrac() {
},
];
return (
<div className={"bg-stone-900 min-h-screen font-geist"}>
<main
className={"max-w-[700px] pt-15 flex flex-col gap-4 mx-auto w-full p-4"}
<main className={"flex flex-col gap-4 w-full"}>
<Link
href={"/protocol"}
className={
"text-stone-500 flex flex-row items-center transition duration-200 hover:text-stone-50 gap-2"
}
>
<NavBar />
<Link
href={"/protocol"}
className={
"text-stone-500 flex flex-row items-center transition duration-200 hover:text-stone-50 gap-2"
}
>
<ArrowLeft size={16} /> Go Back
</Link>
<PageTitle id={"user-agents"}>User Agents</PageTitle>
<Text>
The RAC protocol doesnt have any functionality to identify clients,
so the community decided to use their own solution called{" "}
<b>User Agents</b>.
</Text>
<Text>
User Agents in RAC are implemented by adding an extra Unicode symbol
as a prefix to usernames. For example, a message sent with the Tower
client:
</Text>
<Code>{"▲<zero> Hello, world!"}</Code>
<Text>
The <InlineCode></InlineCode> symbol in front of the username
indicates that this message was sent using the Tower client. The
client should use regex to parse these messages and determine the
client, username, and message.
</Text>
<h3 className={"text-3xl text-stone-300 font-semibold font-rokkitt"}>
Known Agents
</h3>
<Text>
Below is a table of known user agents with their client names and
regular expressions. Clients can also optionally use colored usernames
for each client. You can add your own user agent via a pull request.
</Text>
<Table>
<TableHeader>
<TableRow>
<TableHead className={"w-[150px]"}>Client Name</TableHead>
<TableHead>Regular Expression</TableHead>
<TableHead>Color</TableHead>
<ArrowLeft size={16} /> Go Back
</Link>
<PageTitle id={"user-agents"}>User Agents</PageTitle>
<Text>
The RAC protocol doesnt have any functionality to identify clients, so
the community decided to use their own solution called{" "}
<b>User Agents</b>.
</Text>
<Text>
User Agents in RAC are implemented by adding an extra Unicode symbol as
a prefix to usernames. For example, a message sent with the Tower
client:
</Text>
<Code>{"▲<zero> Hello, world!"}</Code>
<Text>
The <InlineCode></InlineCode> symbol in front of the username indicates
that this message was sent using the Tower client. The client should use
regex to parse these messages and determine the client, username, and
message.
</Text>
<h3 className={"text-3xl text-stone-300 font-semibold font-rokkitt"}>
Known Agents
</h3>
<Text>
Below is a table of known user agents with their client names and
regular expressions. Clients can also optionally use colored usernames
for each client. You can add your own user agent via a pull request.
</Text>
<Table>
<TableHeader>
<TableRow>
<TableHead className={"w-[150px]"}>Client Name</TableHead>
<TableHead>Regular Expression</TableHead>
<TableHead>Color</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{userAgents.map((agent) => (
<TableRow key={agent.client}>
<TableCell className={"font-semibold"}>{agent.client}</TableCell>
<TableCell>
<code>{agent.regex}</code>
</TableCell>
<TableCell>{agent.color}</TableCell>
</TableRow>
</TableHeader>
<TableBody>
{userAgents.map((agent) => (
<TableRow key={agent.client}>
<TableCell className={"font-semibold"}>
{agent.client}
</TableCell>
<TableCell>
<code>{agent.regex}</code>
</TableCell>
<TableCell>{agent.color}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<Footer />
</main>
</div>
))}
</TableBody>
</Table>
</main>
);
}

View File

@ -1,6 +1,4 @@
import NavBar from "@/components/NavBar";
import Footer from "@/components/Footer";
import { ArrowLeft } from "lucide-react";
import { ArrowLeft } from "lucide-react";
import Link from "next/link";
import Text from "@/components/blocks/Text";
import PageTitle from "@/components/blocks/PageTitle";
@ -9,45 +7,37 @@ import InlineCode from "@/components/blocks/InlineCode";
export default function Wrac() {
return (
<div className={"bg-stone-900 min-h-screen font-geist"}>
<main
className={"max-w-[700px] pt-15 flex flex-col gap-4 mx-auto w-full p-4"}
<main className={"flex flex-col gap-4 w-full"}>
<Link
href={"/protocol"}
className={
"text-stone-500 flex flex-row items-center transition duration-200 hover:text-stone-50 gap-2"
}
>
<NavBar />
<Link
href={"/protocol"}
className={
"text-stone-500 flex flex-row items-center transition duration-200 hover:text-stone-50 gap-2"
}
>
<ArrowLeft size={16} /> Go Back
</Link>
<PageTitle id={"websocket-real-address-chat-protocol"}>
WebSocket Real Address Chat Protocol
</PageTitle>
<Text>
WRAC (WebSocket Real Address Chat) is a community-made successor to
RAC that uses WebSockets instead of TCP. It uses the same requests as
RAC, but you should send data in binary format. Unlike regular RAC,
you can use the same connection multiple timesin RAC, you had to
reconnect to the server for every request. This changes how message
receiving works.
</Text>
<Title id={"receiving-messages"}>Receiving messages</Title>
<Text>
Since the connection can now be kept alive and WebSocket uses messages
for transactions, we cant retrieve messages the same way as in RAC.
</Text>
<Text>
Receiving messages in WRAC is done by sending a single packet to the
server with two bytes. The first byte is <InlineCode>0x00</InlineCode>
, which indicates that you want to receive messages, and the second
byte is either <InlineCode>0x01</InlineCode> or{" "}
<InlineCode>0x02</InlineCode>. These two bytes work the same way as in
RAC.
</Text>
<Footer />
</main>
</div>
<ArrowLeft size={16} /> Go Back
</Link>
<PageTitle id={"websocket-real-address-chat-protocol"}>
WebSocket Real Address Chat Protocol
</PageTitle>
<Text>
WRAC (WebSocket Real Address Chat) is a community-made successor to RAC
that uses WebSockets instead of TCP. It uses the same requests as RAC,
but you should send data in binary format. Unlike regular RAC, you can
use the same connection multiple timesin RAC, you had to reconnect to
the server for every request. This changes how message receiving works.
</Text>
<Title id={"receiving-messages"}>Receiving messages</Title>
<Text>
Since the connection can now be kept alive and WebSocket uses messages
for transactions, we cant retrieve messages the same way as in RAC.
</Text>
<Text>
Receiving messages in WRAC is done by sending a single packet to the
server with two bytes. The first byte is <InlineCode>0x00</InlineCode>,
which indicates that you want to receive messages, and the second byte
is either <InlineCode>0x01</InlineCode> or <InlineCode>0x02</InlineCode>
. These two bytes work the same way as in RAC.
</Text>
</main>
);
}