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 # typescript
*.tsbuildinfo *.tsbuildinfo
next-env.d.ts next-env.d.ts
/.idea

View File

@ -1,6 +1,8 @@
import type { Metadata } from "next"; import type { Metadata } from "next";
import { Geist, Rokkitt } from "next/font/google"; import { Geist, Rokkitt } from "next/font/google";
import "./globals.css"; import "./globals.css";
import NavBar from "@/components/NavBar";
import Footer from "@/components/Footer";
const geistSans = Geist({ const geistSans = Geist({
variable: "--font-geist", variable: "--font-geist",
@ -25,9 +27,11 @@ export default function RootLayout({
return ( return (
<html lang="en"> <html lang="en">
<body <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} {children}
<Footer />
</body> </body>
</html> </html>
); );

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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