🌟 feat: Add GetConfigFromAPI to retrieve Egg Inc config data#1930
🌟 feat: Add GetConfigFromAPI to retrieve Egg Inc config data#1930
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a new function GetConfigFromAPI to retrieve configuration data from the Egg Inc API and write it to a JSON file for debugging purposes. The implementation adds zlib compression support for handling compressed API responses.
Key Changes:
- Added
GetConfigFromAPIfunction to fetch and process Egg Inc configuration data from the API - Added zlib compression import to handle compressed API responses
- Implemented JSON file output for debugging in development environments
Comments suppressed due to low confidence (1)
src/ei/ei_api.go:318
- This expression compares an expression to itself.
if protoData == "" {
| go func() { | ||
| jsonData, err := json.MarshalIndent(configResponse, "", " ") | ||
| // Swap all instances of eiUserID with "REDACTED" | ||
| jsonData = []byte(string(jsonData)) |
There was a problem hiding this comment.
The conversion []byte(string(jsonData)) is redundant. The variable jsonData is already of type []byte, so converting it to a string and back to []byte serves no purpose and adds unnecessary overhead. This line can be removed entirely.
| jsonData = []byte(string(jsonData)) |
| } | ||
|
|
||
| // GetConfigFromAPI will download the config data from the Egg Inc API and write it to ei-config.json | ||
| func GetConfigFromAPI(s *discordgo.Session) bool { |
There was a problem hiding this comment.
The function always returns true on success but returns false for multiple different error conditions. This makes it impossible for callers to distinguish between different failure scenarios or understand what went wrong. Consider returning an error instead of a boolean, or using the boolean only to indicate success while logging sufficient context for debugging.
| } | ||
|
|
||
| // GetConfigFromAPI will download the config data from the Egg Inc API and write it to ei-config.json | ||
| func GetConfigFromAPI(s *discordgo.Session) bool { |
There was a problem hiding this comment.
The parameter s *discordgo.Session is declared but never used in the function. If it's not needed for the implementation, consider removing it to keep the function signature clean. If it's being kept for consistency with other API functions or future use, consider adding a comment explaining this.
| func GetConfigFromAPI(s *discordgo.Session) bool { | |
| func GetConfigFromAPI() bool { |
| log.Println("Error marshalling config to JSON:", err) | ||
| } else { | ||
| _ = os.MkdirAll("ttbb-data", os.ModePerm) | ||
| err = os.WriteFile("ttbb-data/ei-config.json", []byte(jsonData), 0644) |
There was a problem hiding this comment.
The conversion []byte(jsonData) is redundant since jsonData is already of type []byte. The variable can be passed directly to os.WriteFile.
| err = os.WriteFile("ttbb-data/ei-config.json", []byte(jsonData), 0644) | |
| err = os.WriteFile("ttbb-data/ei-config.json", jsonData, 0644) |
| protoData := "" | ||
|
|
||
| if protoData == "" { | ||
| clientVersion := uint32(99) | ||
| platformString := "IOS" | ||
| version := "1.35.2" | ||
| build := "111300" | ||
|
|
||
| getConfigRequest := ConfigRequest{ | ||
| Rinfo: &BasicRequestInfo{ | ||
| EiUserId: &config.EIUserIDBasic, | ||
| ClientVersion: &clientVersion, | ||
| Version: &version, | ||
| Build: &build, | ||
| Platform: &platformString, | ||
| }, | ||
| } | ||
|
|
||
| reqBin, err := proto.Marshal(&getConfigRequest) | ||
| if err != nil { | ||
| log.Print(err) | ||
| return false | ||
| } | ||
| values := url.Values{} | ||
| reqDataEncoded := enc.EncodeToString(reqBin) | ||
| values.Set("data", string(reqDataEncoded)) | ||
|
|
||
| response, err := http.PostForm(reqURL, values) | ||
| if err != nil { | ||
| log.Print(err) | ||
| return false | ||
| } | ||
|
|
||
| defer func() { | ||
| if err := response.Body.Close(); err != nil { | ||
| // Handle the error appropriately, e.g., logging or taking corrective actions | ||
| log.Printf("Failed to close: %v", err) | ||
| } | ||
| }() | ||
|
|
||
| // Read the response body | ||
| body, err := io.ReadAll(response.Body) | ||
| if err != nil { | ||
| log.Print(err) | ||
| return false | ||
| } | ||
| protoData = string(body) | ||
| } |
There was a problem hiding this comment.
The variable protoData is initialized to an empty string and immediately checked if it equals an empty string. This condition will always be true, making the entire if block at line 318 dead code. The unconditional block should be executed directly without the initialization and check.
| protoData := "" | |
| if protoData == "" { | |
| clientVersion := uint32(99) | |
| platformString := "IOS" | |
| version := "1.35.2" | |
| build := "111300" | |
| getConfigRequest := ConfigRequest{ | |
| Rinfo: &BasicRequestInfo{ | |
| EiUserId: &config.EIUserIDBasic, | |
| ClientVersion: &clientVersion, | |
| Version: &version, | |
| Build: &build, | |
| Platform: &platformString, | |
| }, | |
| } | |
| reqBin, err := proto.Marshal(&getConfigRequest) | |
| if err != nil { | |
| log.Print(err) | |
| return false | |
| } | |
| values := url.Values{} | |
| reqDataEncoded := enc.EncodeToString(reqBin) | |
| values.Set("data", string(reqDataEncoded)) | |
| response, err := http.PostForm(reqURL, values) | |
| if err != nil { | |
| log.Print(err) | |
| return false | |
| } | |
| defer func() { | |
| if err := response.Body.Close(); err != nil { | |
| // Handle the error appropriately, e.g., logging or taking corrective actions | |
| log.Printf("Failed to close: %v", err) | |
| } | |
| }() | |
| // Read the response body | |
| body, err := io.ReadAll(response.Body) | |
| if err != nil { | |
| log.Print(err) | |
| return false | |
| } | |
| protoData = string(body) | |
| } | |
| clientVersion := uint32(99) | |
| platformString := "IOS" | |
| version := "1.35.2" | |
| build := "111300" | |
| getConfigRequest := ConfigRequest{ | |
| Rinfo: &BasicRequestInfo{ | |
| EiUserId: &config.EIUserIDBasic, | |
| ClientVersion: &clientVersion, | |
| Version: &version, | |
| Build: &build, | |
| Platform: &platformString, | |
| }, | |
| } | |
| reqBin, err := proto.Marshal(&getConfigRequest) | |
| if err != nil { | |
| log.Print(err) | |
| return false | |
| } | |
| values := url.Values{} | |
| reqDataEncoded := enc.EncodeToString(reqBin) | |
| values.Set("data", string(reqDataEncoded)) | |
| response, err := http.PostForm(reqURL, values) | |
| if err != nil { | |
| log.Print(err) | |
| return false | |
| } | |
| defer func() { | |
| if err := response.Body.Close(); err != nil { | |
| // Handle the error appropriately, e.g., logging or taking corrective actions | |
| log.Printf("Failed to close: %v", err) | |
| } | |
| }() | |
| // Read the response body | |
| body, err := io.ReadAll(response.Body) | |
| if err != nil { | |
| log.Print(err) | |
| return false | |
| } | |
| protoData := string(body) |
| } | ||
|
|
||
| decodedAuthBuf := &AuthenticatedMessage{} | ||
| rawDecodedText, _ := enc.DecodeString(protoData) |
There was a problem hiding this comment.
The error returned from enc.DecodeString is being ignored. If the base64 decoding fails, rawDecodedText will be nil or invalid, which could cause the subsequent proto.Unmarshal to fail with an unclear error message. The error should be checked and handled appropriately.
| rawDecodedText, _ := enc.DecodeString(protoData) | |
| rawDecodedText, decodeErr := enc.DecodeString(protoData) | |
| if decodeErr != nil { | |
| log.Print(decodeErr) | |
| return false | |
| } |
| // Swap all instances of eiUserID with "REDACTED" | ||
| jsonData = []byte(string(jsonData)) | ||
| jsonData = []byte(RedactUserInfo(string(jsonData), config.EIUserIDBasic)) | ||
| if err != nil { | ||
| log.Println("Error marshalling config to JSON:", err) | ||
| } else { | ||
| _ = os.MkdirAll("ttbb-data", os.ModePerm) | ||
| err = os.WriteFile("ttbb-data/ei-config.json", []byte(jsonData), 0644) | ||
| if err != nil { | ||
| log.Print(err) | ||
| } |
There was a problem hiding this comment.
The error check is performed after the jsonData variable has already been used on lines 406-407. If json.MarshalIndent fails, jsonData will be nil, causing a panic when attempting to convert it. The error check should occur immediately after marshaling and before using jsonData.
| // Swap all instances of eiUserID with "REDACTED" | |
| jsonData = []byte(string(jsonData)) | |
| jsonData = []byte(RedactUserInfo(string(jsonData), config.EIUserIDBasic)) | |
| if err != nil { | |
| log.Println("Error marshalling config to JSON:", err) | |
| } else { | |
| _ = os.MkdirAll("ttbb-data", os.ModePerm) | |
| err = os.WriteFile("ttbb-data/ei-config.json", []byte(jsonData), 0644) | |
| if err != nil { | |
| log.Print(err) | |
| } | |
| if err != nil { | |
| log.Println("Error marshalling config to JSON:", err) | |
| return | |
| } | |
| // Swap all instances of eiUserID with "REDACTED" | |
| jsonData = []byte(RedactUserInfo(string(jsonData), config.EIUserIDBasic)) | |
| _ = os.MkdirAll("ttbb-data", os.ModePerm) | |
| err = os.WriteFile("ttbb-data/ei-config.json", []byte(jsonData), 0644) | |
| if err != nil { | |
| log.Print(err) |
No description provided.