refactor: move navbar and footer to layout.tsx
This commit is contained in:
parent
c52e971b36
commit
66b780eaad
2
.gitignore
vendored
2
.gitignore
vendored
@ -39,3 +39,5 @@ yarn-error.log*
|
|||||||
# typescript
|
# typescript
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
|
|
||||||
|
/.idea
|
@ -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>
|
||||||
);
|
);
|
||||||
|
@ -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 we’ll review it.
|
||||||
</Text>
|
</Text>
|
||||||
<Text>
|
</main>
|
||||||
Want to add your project to Racinfo? Make a pull request on our
|
|
||||||
official GitHub repository, and we’ll review it.
|
|
||||||
</Text>
|
|
||||||
<Footer />
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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. There’s also a community-made successor called
|
||||||
<Text>
|
WRAC. It’s 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. There’s also a community-made successor called
|
<Text>
|
||||||
WRAC. It’s 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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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 don’t 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 don’t 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, let’s
|
||||||
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, let’s
|
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 doesn’t 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 doesn’t 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 shouldn’t
|
||||||
<InlineCode>{"<>"}</InlineCode>. This approach makes parsing messages
|
be anonymous unless they’re authorized. Still, most clients ignore the
|
||||||
easier with regex. Learn more about user agents and how to create your
|
IP address and don’t 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 packet—not separately. After that, you won’t receive
|
||||||
be ignored for this. This idea, introduced by Sugoma, means that
|
anything from the server, even if there’s an error. So your final
|
||||||
clients shouldn’t be anonymous unless they’re authorized. Still, most
|
message should look like this:
|
||||||
clients ignore the IP address and don’t 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 packet—not separately. After that, you won’t
|
<InlineCode>0x02</InlineCode> and after that, separating by{" "}
|
||||||
receive anything from the server, even if there’s an error. So your
|
<InlineCode>\n</InlineCode>, send user'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 won’t 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 doesn’t 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'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 won’t send any
|
Sugoma for people who don’t want to expose their IP address to everyone.
|
||||||
response. If not, the server will send a <InlineCode>0x01</InlineCode>{" "}
|
</Text>
|
||||||
byte if the user doesn’t 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 don’t 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. There’s 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.
|
don’t 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. There’s 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>
|
||||||
don’t 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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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 doesn’t 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 doesn’t 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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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 times—in 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 can’t retrieve messages the same way as in RAC.
|
||||||
you can use the same connection multiple times—in 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 can’t 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>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user