forked from Rosetta/landing
Новый лендинг
This commit is contained in:
@@ -16,6 +16,22 @@
|
||||
border: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-5));
|
||||
}
|
||||
|
||||
.protoSubheading {
|
||||
margin: 30px 0 12px;
|
||||
color: light-dark(var(--mantine-color-dark-8), var(--mantine-color-dark-0));
|
||||
font-size: 17px;
|
||||
font-weight: 650;
|
||||
}
|
||||
|
||||
.layerExamples {
|
||||
margin: 18px 0 24px;
|
||||
}
|
||||
|
||||
.layerExamples .protoCode {
|
||||
height: calc(100% - 30px);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.docsLink {
|
||||
display: inline-block;
|
||||
margin-top: 44px;
|
||||
|
||||
@@ -374,13 +374,147 @@ field_id:uint8 | wire_type:uint8 | [length:uint16] | value
|
||||
</LegalList>
|
||||
</LegalSection>
|
||||
|
||||
<LegalSection title="Layers and compatibility">
|
||||
<LegalSection title="Protocol versioning">
|
||||
<LegalText>
|
||||
Protocol layers are generated from RCC YAML schemas. Every layer defines
|
||||
packet IDs, field IDs, primitive types, reusable types, enumerations, and
|
||||
optional values. Keeping field IDs stable allows compatible decoders to
|
||||
read known fields while the schema evolves.
|
||||
Each <Code>layer.N.yml</Code> file is a complete protocol snapshot. Its
|
||||
top-level <Code>version</Code> is the layer number. RCC sorts all layers by
|
||||
that number, rejects duplicate versions, and builds a timeline for every
|
||||
packet, field, type, and enum value. A newer layer repeats the definitions
|
||||
that still exist and adds, removes, or makes fields optional as needed.
|
||||
</LegalText>
|
||||
<LegalText>
|
||||
Packet IDs should remain stable, and RCC explicitly validates field-ID
|
||||
reuse inside every packet and type. An existing field ID cannot be assigned
|
||||
to a different field name or type in a later layer. A new field receives a
|
||||
new ID; an optional field may be omitted by older peers. The server
|
||||
generator keeps version-aware codecs for the supported range, while a
|
||||
client generator produces the current layer.
|
||||
</LegalText>
|
||||
<LegalText>
|
||||
RCC does not negotiate a layer over the network by itself. The connection
|
||||
or handshake code selects a version supported by both peers, then passes
|
||||
that number to the generated server codec. The registry exposes the
|
||||
minimum and maximum compiled versions, and the codec includes only fields
|
||||
whose lifetime contains the selected version. TLV fields that are not used
|
||||
by that layer do not become properties of the decoded packet.
|
||||
</LegalText>
|
||||
|
||||
<Title order={3} className={classes.protoSubheading}>
|
||||
Two simple layers
|
||||
</Title>
|
||||
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md" className={classes.layerExamples}>
|
||||
<Box>
|
||||
<Text fw={650} size="sm">Layer 1</Text>
|
||||
<Code block className={classes.protoCode}>
|
||||
{`version: 1
|
||||
|
||||
packets:
|
||||
Profile:
|
||||
id: 10
|
||||
fields:
|
||||
- id: 1
|
||||
name: username
|
||||
type: string`}
|
||||
</Code>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fw={650} size="sm">Layer 2</Text>
|
||||
<Code block className={classes.protoCode}>
|
||||
{`version: 2
|
||||
|
||||
packets:
|
||||
Profile:
|
||||
id: 10
|
||||
fields:
|
||||
- id: 1
|
||||
name: username
|
||||
type: string
|
||||
- id: 2
|
||||
name: displayName?
|
||||
type: string`}
|
||||
</Code>
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
<LegalText>
|
||||
Layer 2 preserves packet ID <Code>10</Code> and field ID
|
||||
<Code> 1</Code>, then introduces optional field ID <Code>2</Code>. A layer 1
|
||||
peer sends and reads only <Code>username</Code>. A layer 2 peer can include
|
||||
<Code> displayName</Code>, but does not require it.
|
||||
</LegalText>
|
||||
|
||||
<Title order={3} className={classes.protoSubheading}>
|
||||
Simplified server output
|
||||
</Title>
|
||||
<LegalText>
|
||||
In server mode RCC combines both snapshots into one model and a codec that
|
||||
receives the negotiated version. The generated source is more verbose; the
|
||||
following excerpt keeps only the versioning decisions.
|
||||
</LegalText>
|
||||
<Code block className={classes.protoCode}>
|
||||
{`public class PacketProfile extends Packet {
|
||||
public String username;
|
||||
public String displayName; // introduced in layer 2
|
||||
}
|
||||
|
||||
public class PacketProfileCodec {
|
||||
private static final int F_USERNAME = 1;
|
||||
private static final int F_DISPLAY_NAME = 2;
|
||||
|
||||
public PacketProfile decode(ByteBuf data, int version) {
|
||||
TlvReader reader = new TlvReader(data);
|
||||
PacketProfile packet = new PacketProfile();
|
||||
packet.username = requireField(reader.getString(F_USERNAME));
|
||||
|
||||
if (version >= 2) {
|
||||
packet.displayName = reader.getString(F_DISPLAY_NAME);
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
public ByteBuf encode(PacketProfile packet, int version) {
|
||||
TlvWriter writer = new TlvWriter();
|
||||
writer.writeString(F_USERNAME, packet.username);
|
||||
|
||||
if (version >= 2 && packet.displayName != null) {
|
||||
writer.writeString(F_DISPLAY_NAME, packet.displayName);
|
||||
}
|
||||
return writer.getBuffer();
|
||||
}
|
||||
}`}
|
||||
</Code>
|
||||
<LegalText>
|
||||
RCC also writes the supported interval to the generated registry. A packet
|
||||
codec can reject a layer older than the packet's introduction. Removed
|
||||
fields remain available to the server model and codec only for the layers
|
||||
in which they existed; enum values receive equivalent
|
||||
<Code> isSupportedInVersion</Code> checks.
|
||||
</LegalText>
|
||||
<Code block className={classes.protoCode}>
|
||||
{`public final class RccGeneratedPacketRegistry {
|
||||
public static final int MIN_VERSION = 1;
|
||||
public static final int MAX_VERSION = 2;
|
||||
public static final int PACKET_PROFILE_ID = 10;
|
||||
}`}
|
||||
</Code>
|
||||
|
||||
<Title order={3} className={classes.protoSubheading}>
|
||||
Latest client output
|
||||
</Title>
|
||||
<LegalText>
|
||||
A TypeScript client is generated from the latest layer, so application code
|
||||
sees the current shape and the optional marker directly.
|
||||
</LegalText>
|
||||
<Code block className={classes.protoCode}>
|
||||
{`export class PacketProfile extends Packet {
|
||||
username!: string;
|
||||
displayName?: string;
|
||||
}
|
||||
|
||||
export class RccGeneratedPacketRegistry {
|
||||
static readonly VERSION = 2;
|
||||
static readonly PACKET_PROFILE_ID = 10;
|
||||
}`}
|
||||
</Code>
|
||||
</LegalSection>
|
||||
|
||||
<LegalSection title="How an RCC YAML layer is structured">
|
||||
@@ -707,10 +841,11 @@ export function ProtoDocsPage() {
|
||||
<Box className={classes.documentation}>
|
||||
<Box className={classes.filters}>
|
||||
<TextInput
|
||||
label="Search"
|
||||
value={search}
|
||||
onChange={(event) => setSearch(event.currentTarget.value)}
|
||||
leftSection={<IconSearch size={17} />}
|
||||
placeholder="Search packets, types, fields, or enums"
|
||||
placeholder="Packets, types, fields, or enums"
|
||||
aria-label="Search Proto documentation"
|
||||
/>
|
||||
<Text c="dimmed" size="xs">
|
||||
|
||||
@@ -40,12 +40,12 @@
|
||||
}
|
||||
|
||||
.searchInput input {
|
||||
height: 64px;
|
||||
padding-inline: 58px;
|
||||
border-color: transparent;
|
||||
height: 56px;
|
||||
padding-inline: 50px;
|
||||
border-color: light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-4));
|
||||
background: light-dark(var(--mantine-color-white), var(--mantine-color-dark-7));
|
||||
box-shadow: 0 12px 38px rgba(25, 113, 194, 0.16);
|
||||
font-size: 17px;
|
||||
box-shadow: none;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.searchInput input:focus {
|
||||
|
||||
@@ -108,9 +108,6 @@ export function SupportPage() {
|
||||
</ThemeIcon>
|
||||
|
||||
<Stack align="center" gap="sm" className={classes.heroContent}>
|
||||
<Text fw={700} size="sm" c="blue.8">
|
||||
Rosetta Support
|
||||
</Text>
|
||||
<Title order={1}>How can we help?</Title>
|
||||
<Text c="blue.9" ta="center" className={classes.heroDescription}>
|
||||
Search account access, messaging, media, privacy, and security help.
|
||||
@@ -135,8 +132,8 @@ export function SupportPage() {
|
||||
}
|
||||
placeholder="Describe your problem"
|
||||
aria-label="Search Rosetta support"
|
||||
size="xl"
|
||||
radius="xl"
|
||||
size="lg"
|
||||
radius="sm"
|
||||
className={classes.searchInput}
|
||||
/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user