Skip to content

Commit

Permalink
[Session String Generator] Fix mtcute serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
rojvv committed Mar 20, 2024
1 parent bb02fcd commit dc39157
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 20 deletions.
7 changes: 3 additions & 4 deletions islands/SessionStringGenerator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -266,13 +266,12 @@ async function generateSessionString(library: ValidLibrary) {
const me = await client.getMe();
sessionString.value = serializeMtcute(
testMode,
dcId,
ip,
80,
{ id: dcId, ip, port: 80 },
null,
me.id,
me.isBot,
authKey,
); // TODO: tests
);
return;
}
case "mtkruto":
Expand Down
59 changes: 44 additions & 15 deletions lib/session_string.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -238,31 +238,60 @@ export function deserializePyrogram(string: string): CommonSessionStringFormat {
*/
export function serializeMtcute(
testMode: boolean,
dcId: number,
ip: string,
port: number,
primaryDc: MtcuteDC,
mediaDc: MtcuteDC | null,
userId: number,
isBot: boolean,
authKey: Uint8Array,
) {
const writer = new TLRawWriter();
writer.write(new Uint8Array([0x03])); // version
writer.writeInt32(
MTCUTE_HAS_SELF_FLAG | (testMode ? MTCUTE_TEST_MODE_FLAG : 0),
); // flags

writer.write(new Uint8Array([0x01])); // dc_version
writer.writeBytes(new Uint8Array([dcId])); // dc_id
writer.writeInt32(ip.includes(":") ? MTCUTE_IPV6_FLAG : 0); // dc_flags
writer.writeString(ip); // dc_ip
writer.writeInt32(port); // dc_port
let flags = MTCUTE_HAS_SELF_FLAG;
if (mediaDc != null) {
flags |= MTCUTE_MEDIA_DC_FLAG;
}
if (testMode) {
flags |= MTCUTE_TEST_MODE_FLAG;
}
writer.writeInt32(flags); // flags

writer.writeBytes(serializeMtcuteDc(primaryDc));
if (mediaDc != null) {
writer.writeBytes(serializeMtcuteDc(mediaDc));
}

writer.writeInt64(BigInt(userId)); // user_id
writer.write(new Uint8Array([isBot ? 1 : 0])); // is_bot
writer.write(authKey); // authKey
writer.writeInt32(isBot ? 0x997275b5 : 0xbc799737, false); // is_bot
writer.writeBytes(authKey); // authKey

return base64EncodeUrlSafe(writer.buffer);
}
function serializeMtcuteDc(dc: MtcuteDC) {
const writer = new TLRawWriter();
writer.write(new Uint8Array([0x01])); // dc_version
writer.write(new Uint8Array([dc.id])); // dc_id
let flags = 0;
if (dc.ip.includes(":")) {
flags |= MTCUTE_DC_IPV6_FLAG;
}
if (dc.media) {
flags |= MTCUTE_DC_MEDIA_FLAG;
}
writer.write(new Uint8Array([flags])); // dc_flags
writer.writeString(dc.ip); // dc_ip
writer.writeInt32(dc.port); // dc_port
return writer.buffer;
}
export interface MtcuteDC {
id: number;
ip: string;
port: number;
media?: true;
}
const MTCUTE_HAS_SELF_FLAG = 1;
const MTCUTE_TEST_MODE_FLAG = 2; // TODO: flag 4?
const MTCUTE_IPV6_FLAG = 1;
const MTCUTE_TEST_MODE_FLAG = 2;
const MTCUTE_MEDIA_DC_FLAG = 4;

const MTCUTE_DC_IPV6_FLAG = 1;
const MTCUTE_DC_MEDIA_FLAG = 2;
33 changes: 32 additions & 1 deletion lib/session_string_test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { assertEquals } from "$std/assert/mod.ts";
import { serializeMtcute } from "./session_string.tsx";
import { deserializeTelethon } from "./session_string.tsx";
import {
deserializeGramjs,
Expand Down Expand Up @@ -47,7 +48,7 @@ Deno.test("Telethon", async (t) => {
const serialized =
"1AwAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";

await t.step("serializeTelethon", () => {
await t.step("serialize", () => {
assertEquals(
serializeTelethon(dc, ip, port, authKey),
serialized,
Expand Down Expand Up @@ -85,3 +86,33 @@ Deno.test("GramJS", async (t) => {
assertEquals(deserialized.authKey, authKey);
});
});

Deno.test("mtcute", async (t) => {
const serialized =
"AwUAAAAXAQIADjE0OS4xNTQuMTY3LjUwALsBAAAXAQICDzE0OS4xNTQuMTY3LjIyMrsBAAA5MAAAAAAAADeXebwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
const primaryDc = { id: 2, ip: "149.154.167.50", port: 443 } as const;
const mediaDc = {
id: 2,
ip: "149.154.167.222",
port: 443,
media: true,
} as const;
const isBot = false;
const userId = 12345;
const testMode = false;
const authKey = new Uint8Array(32);

await t.step("serialize", () => {
assertEquals(
serializeMtcute(
testMode,
primaryDc,
mediaDc,
userId,
isBot,
authKey,
),
serialized,
);
});
});

0 comments on commit dc39157

Please sign in to comment.