Skip to content

Commit

Permalink
panic: on error code 4294966892 (-404), reauthenticate, revamp tl par…
Browse files Browse the repository at this point in the history
…ser, workflow
  • Loading branch information
AmarnathCJD committed Mar 13, 2024
1 parent 187a9aa commit 5029787
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 23 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/tlparser.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: TLParser Workflow

on:
push:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.22

- name: Build and run tlgen
run: |
go build -o tlgen ./internal/cmd/tlgen
./tlgen
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: Auto LTL
title: Auto LTL
body: Automatically generated pull request from TLParser workflow
212 changes: 201 additions & 11 deletions internal/cmd/tlgen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,78 @@ package main

import (
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"regexp"
"strings"
"time"

"github.com/amarnathcjd/gogram/internal/cmd/tlgen/gen"
"github.com/amarnathcjd/gogram/internal/cmd/tlgen/tlparser"
)

const helpMsg = `tlgen
usage: tlgen input_file.tl output_dir/
THIS TOOL IS USING ONLY FOR AUTOMATIC CODE
GENERATION, DO NOT GENERATE FILES BY HAND!
No, seriously. Don't. go generate is amazing. You
are amazing too, but lesser 😏
`
const license = `-`
const (
API_SOURCE = "https://raw.githubusercontent.com/telegramdesktop/tdesktop/dev/Telegram/SourceFiles/mtproto/scheme/api.tl"
tlLOC = "../../../schemes/api.tl"
desLOC = "../../../telegram/"
)

const helpMsg = `welcome to gogram's TL generator (c) @amarnathcjd`

func main() {
if len(os.Args) == 0 || len(os.Args) == 1 {
currentLocalAPIVersionFile := filepath.Join(desLOC, "const.go")
currentLocalAPIVersion, err := os.ReadFile(currentLocalAPIVersionFile)
if err != nil {
panic(err)
}

reg := regexp.MustCompile(`ApiVersion = \d+`)
str := string(currentLocalAPIVersion)
llayer := reg.FindString(str)
llayer = strings.TrimPrefix(llayer, "ApiVersion = ")

currentRemoteAPIVersion, err := http.Get(API_SOURCE)
if err != nil {
panic(err)
}

remoteAPIVersion, err := io.ReadAll(currentRemoteAPIVersion.Body)
if err != nil {
panic(err)
}

reg = regexp.MustCompile(`// LAYER \d+`)
str = string(remoteAPIVersion)
rlayer := reg.FindString(str)
rlayer = strings.TrimPrefix(rlayer, "// LAYER ")

if !strings.EqualFold(llayer, rlayer) {
fmt.Println("Local API version is", llayer, "and remote API version is", rlayer)
fmt.Println("Performing update")

file, err := os.OpenFile(tlLOC, os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
panic(err)
}

file.Truncate(0)
file.Seek(0, 0)
file.WriteString(string(remoteAPIVersion))

root(tlLOC, desLOC)
} else {
fmt.Println("Local API version is", llayer, "and remote API version is", rlayer)
fmt.Println("No update required")
}

return
}

if len(os.Args) != 3 {
fmt.Println(helpMsg)
fmt.Print(helpMsg)
return
}

Expand All @@ -30,6 +84,7 @@ func main() {
}

func root(tlfile, outdir string) error {
startTime := time.Now()
b, err := os.ReadFile(tlfile)
if err != nil {
return fmt.Errorf("read schema file: %w", err)
Expand All @@ -40,10 +95,145 @@ func root(tlfile, outdir string) error {
return fmt.Errorf("parse schema file: %w", err)
}

g, err := gen.NewGenerator(schema, license, outdir)
g, err := gen.NewGenerator(schema, "(c) @amarnathcjd", outdir)
if err != nil {
return err
}

return g.Generate()
err = g.Generate()
if err != nil {
return fmt.Errorf("generate code: %w", err)
}

fmt.Println("Generated code in", outdir, "in", time.Since(startTime))
minorFixes(outdir, getAPILayerFromFile(tlfile))
return nil
}

func getAPILayerFromFile(tlfile string) string {
b, err := os.ReadFile(tlfile)
if err != nil {
return "0"
}

// last line:: // LAYER 176
lines := strings.Split(string(b), "\n")
if len(lines) < 2 {
return "0"
}

lastLine := lines[len(lines)-1]
if !strings.HasPrefix(lastLine, "// LAYER") {
return "0"
}

return strings.TrimSpace(strings.TrimPrefix(lastLine, "// LAYER"))
}

func minorFixes(outdir string, layer string) {
execWorkDir, err := os.Getwd()
if err != nil {
panic(err)
}

execWorkDir = filepath.Join(execWorkDir, outdir)
fmt.Println("Applying minor fixes to generated code in", execWorkDir)

replace(filepath.Join(execWorkDir, "methods_gen.go"), "return bool", "return false")
replace(filepath.Join(execWorkDir, "methods_gen.go"), `if err != nil {
return nil, errors.Wrap(err, "sending UsersGetUsers")
}
resp, ok := responseData.([]User)
if !ok {
panic("got invalid response type: " + reflect.TypeOf(responseData).String())
}`, `if err != nil {
return nil, errors.Wrap(err, "sending UsersGetUsers")
}
resp, ok := responseData.([]User)
if !ok {
if _, ok := responseData.([]*UserObj); ok { // Temp Fix till Problem is Identified
var users []User = make([]User, len(responseData.([]*UserObj)))
for i, user := range responseData.([]*UserObj) {
users[i] = user
}
return users, nil
}
panic("got invalid response type: " + reflect.TypeOf(responseData).String())
}`)

replace(filepath.Join(execWorkDir, "methods_gen.go"), `errors []SecureValueError`, `errorsw []SecureValueError`)
replace(filepath.Join(execWorkDir, "methods_gen.go"), `responseData, err := c.MakeRequest(&UsersSetSecureValueErrorsParams{
Errors: errors,
ID: id,
})`, `responseData, err := c.MakeRequest(&UsersSetSecureValueErrorsParams{
Errors: errorsw,
ID: id,
})`)

replace(filepath.Join(execWorkDir, "enums_gen.go"), `Null Null`, `NullCrc Null`)

replace(filepath.Join(execWorkDir, "init_gen.go"), `Null,`, `NullCrc,`)
if layer != "0" {
// replace ApiVersion = 174
fmt.Println("Updating ApiVersion to", layer)
file, err := os.OpenFile(filepath.Join(execWorkDir, "const.go"), os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
panic(err)
}

content, err := io.ReadAll(file)
if err != nil {
panic(err)
}

reg := regexp.MustCompile(`ApiVersion = \d+`)
str := string(content)

str = reg.ReplaceAllString(str, "ApiVersion = "+layer)

file.Truncate(0)
file.Seek(0, 0)

_, err = file.Write([]byte(str))
if err != nil {
panic(err)
}
}
}

func replace(filename, old, new string) {
f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
panic(err)
}

content, err := io.ReadAll(f)
if err != nil {
panic(err)
}

//fmt.Println("Replacing", old, "with", new, "in", filename)

str := string(content)
str = strings.Replace(str, old, new, -1)

// truncate the file before writing
err = f.Truncate(0)
if err != nil {
panic(err)
}

_, err = f.Seek(0, 0)
if err != nil {
panic(err)
}

_, err = f.Write([]byte(str))
if err != nil {
panic(err)
}
}
26 changes: 14 additions & 12 deletions mtproto.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ func (m *MTProto) Ping() time.Duration {

func (m *MTProto) startReadingResponses(ctx context.Context) {
m.routineswg.Add(1)

go func() {
defer m.routineswg.Done()
for {
Expand All @@ -413,7 +414,6 @@ func (m *MTProto) startReadingResponses(ctx context.Context) {
return
}
err := m.readMsg()
//errors.Is(err, io.EOF)

if err != nil {
if strings.Contains(err.Error(), "unexpected error: unexpected EOF") {
Expand Down Expand Up @@ -442,16 +442,18 @@ func (m *MTProto) startReadingResponses(ctx context.Context) {
}
return
default:
if e, ok := err.(transport.ErrCode); ok && e != 4294966892 {
err = m.makeAuthKey()
if err != nil {
m.Logger.Error(errors.Wrap(err, "making auth key"))
}
} else {
err = m.Reconnect(false)
if err != nil {
m.Logger.Error(errors.Wrap(err, "reconnecting error"))
switch e := err.(type) {
case *ErrResponseCode:
if e.Code == 4294966892 {
m.Logger.Error(errors.New("[AUTH_KEY_INVALID] the auth key is invalid and needs to be reauthenticated (code -404)"))
panic("[AUTH_KEY_INVALID] the auth key is invalid and needs to be reauthenticated (code -404)")
}
case *transport.ErrCode:
m.Logger.Error(errors.New("[TRANSPORT_ERROR] - " + e.Error()))
}

if err := m.Reconnect(false); err != nil {
m.Logger.Error(errors.Wrap(err, "reconnecting"))
}
}
}
Expand Down Expand Up @@ -620,12 +622,12 @@ func (m *MTProto) offsetTime() {
}

if err := json.NewDecoder(resp.Body).Decode(&timeResponse); err != nil {
m.Logger.Error(errors.Wrap(err, "offsetting time"))
m.Logger.Error(errors.Wrap(err, "off-setting time"))
return
}

m.timeOffset = timeResponse.Unixtime - currentLocalTime
m.Logger.Info("SystemTime is out of sync, offsetting time by " + strconv.FormatInt(m.timeOffset, 10) + " seconds")
m.Logger.Info("system time is out of sync, off-setting time by " + strconv.FormatInt(m.timeOffset, 10) + " seconds")
}

func closeOnCancel(ctx context.Context, c io.Closer) {
Expand Down

0 comments on commit 5029787

Please sign in to comment.