Compare commits
	
		
			5 Commits
		
	
	
		
			2a42301c25
			...
			9f4be9e986
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9f4be9e986 | |||
| fa254c60f7 | |||
| 00db797d65 | |||
| 8b001e499a | |||
| 62faa6c974 | 
| @@ -3,6 +3,7 @@ token = "" | ||||
| appid = "" | ||||
| guildid = "" | ||||
| category_id = "" | ||||
| admin_roles = [""] | ||||
|  | ||||
| [database] | ||||
| host = "" | ||||
| @@ -11,4 +12,4 @@ name = "" | ||||
| username = "" | ||||
| password = "" | ||||
|  | ||||
| admin_roles = [""] | ||||
|  | ||||
|   | ||||
							
								
								
									
										194
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										194
									
								
								main.go
									
									
									
									
									
								
							| @@ -1,19 +1,36 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"database/sql" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"mime/multipart" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
| 	"os/signal" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"syscall" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/BurntSushi/toml" | ||||
| 	"github.com/bwmarrin/discordgo" | ||||
| 	_ "github.com/lib/pq" | ||||
| 	"github.com/lib/pq" | ||||
| ) | ||||
|  | ||||
| type UserResponse struct { | ||||
| 	ID           string   `json:"id"` | ||||
| 	Username     string   `json:"username"` | ||||
| 	Subscription bool     `json:"subscription"` | ||||
| 	Group        string   `json:"group"` | ||||
| 	Expiration   string   `json:"expiration"` | ||||
| 	Versions     []string `json:"versions"` | ||||
| 	PFP          string   `json:"pfp"` | ||||
| 	Message      int      `json:"message"` | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	config Config | ||||
| 	client *discordgo.Session | ||||
| @@ -21,16 +38,16 @@ var ( | ||||
| ) | ||||
|  | ||||
| type Config struct { | ||||
| 	Discord    Discord  `toml:"discord"` | ||||
| 	Database   Database `toml:"database"` | ||||
| 	AdminRoles []string `toml:"admin_roles"` | ||||
| 	Discord  Discord  `toml:"discord"` | ||||
| 	Database Database `toml:"database"` | ||||
| } | ||||
|  | ||||
| type Discord struct { | ||||
| 	Token      string `toml:"token"` | ||||
| 	AppID      string `toml:"appid"` | ||||
| 	GuildID    string `toml:"guildid"` | ||||
| 	CategoryID string `toml:"category_id"` | ||||
| 	Token      string   `toml:"token"` | ||||
| 	AppID      string   `toml:"appid"` | ||||
| 	GuildID    string   `toml:"guildid"` | ||||
| 	CategoryID string   `toml:"category_id"` | ||||
| 	AdminRoles []string `toml:"admin_roles"` | ||||
| } | ||||
|  | ||||
| type Database struct { | ||||
| @@ -223,6 +240,22 @@ var ( | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 			_, baseUrl := getTableNameAndBaseURL(selectedOption) | ||||
| 			userUID, _ := fetchUserID(userName, baseUrl) | ||||
| 			if userUID == 0 { | ||||
| 				err := client.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ | ||||
| 					Type: discordgo.InteractionResponseChannelMessageWithSource, | ||||
| 					Data: &discordgo.InteractionResponseData{ | ||||
| 						Content: fmt.Sprintf("Account not found for %s", softwareType), | ||||
| 						Flags:   discordgo.MessageFlagsEphemeral, | ||||
| 					}, | ||||
| 				}) | ||||
| 				if err != nil { | ||||
| 					log.Println("Error sending interaction response:", err) | ||||
| 				} | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 			channel, err := client.GuildChannelCreateComplex(guildID, discordgo.GuildChannelCreateData{ | ||||
| 				Name:     fmt.Sprintf("reset-%s-%s", softwareType, userName), | ||||
| 				Type:     discordgo.ChannelTypeGuildText, | ||||
| @@ -240,8 +273,14 @@ var ( | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 			for _, roleID := range config.AdminRoles { | ||||
| 				client.ChannelPermissionSet(channel.ID, roleID, discordgo.PermissionOverwriteTypeRole, discordgo.PermissionViewChannel, 0) | ||||
| 			for _, roleID := range config.Discord.AdminRoles { | ||||
| 				if roleID != "" { | ||||
| 					err := client.ChannelPermissionSet(channel.ID, roleID, discordgo.PermissionOverwriteTypeRole, discordgo.PermissionViewChannel|discordgo.PermissionSendMessages, 0) | ||||
| 					if err != nil { | ||||
| 						log.Printf("Error setting permissions for role %s: %v", roleID, err) | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 			} | ||||
|  | ||||
| 			err = client.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ | ||||
| @@ -264,12 +303,12 @@ var ( | ||||
| 							discordgo.Button{ | ||||
| 								Label:    "Accept", | ||||
| 								Style:    discordgo.PrimaryButton, | ||||
| 								CustomID: fmt.Sprintf("accept_%s_%s", userID, softwareType), | ||||
| 								CustomID: fmt.Sprintf("accept_%s_%s_%d", userID, softwareType, userUID), | ||||
| 							}, | ||||
| 							discordgo.Button{ | ||||
| 								Label:    "Decline", | ||||
| 								Style:    discordgo.DangerButton, | ||||
| 								CustomID: fmt.Sprintf("decline_%s_%s", userID, softwareType), | ||||
| 								CustomID: fmt.Sprintf("decline_%s_%s_%d", userID, softwareType, userUID), | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
| @@ -283,12 +322,13 @@ var ( | ||||
| 		"accept": func(client *discordgo.Session, i *discordgo.InteractionCreate) { | ||||
| 			data := i.MessageComponentData().CustomID | ||||
| 			parts := strings.Split(data, "_") | ||||
| 			if len(parts) != 3 { | ||||
| 			if len(parts) != 4 { | ||||
| 				log.Println("Invalid accept button custom ID") | ||||
| 				return | ||||
| 			} | ||||
| 			userID := parts[1] | ||||
| 			softwareType := parts[2] | ||||
| 			userUID, _ := strconv.Atoi(parts[3]) | ||||
|  | ||||
| 			member, err := client.GuildMember(i.GuildID, userID) | ||||
| 			if err != nil { | ||||
| @@ -298,6 +338,13 @@ var ( | ||||
| 			userName := getUsernameFromMember(member) | ||||
|  | ||||
| 			reset(userName, softwareType) | ||||
| 			tableName, _ := getTableNameAndBaseURL(strings.ToLower(softwareType)) | ||||
|  | ||||
| 			_, err = resetAndVerify(tableName, int(userUID)) | ||||
| 			if err != nil { | ||||
| 				log.Println("Error resetting hwid:", err) | ||||
| 			} | ||||
| 			log.Printf("Reset the HWID of user %s with UID %d for %s", userName, userUID, softwareType) | ||||
|  | ||||
| 			err = client.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ | ||||
| 				Type: discordgo.InteractionResponseChannelMessageWithSource, | ||||
| @@ -330,7 +377,7 @@ var ( | ||||
| 		"decline": func(client *discordgo.Session, i *discordgo.InteractionCreate) { | ||||
| 			data := i.MessageComponentData().CustomID | ||||
| 			parts := strings.Split(data, "_") | ||||
| 			if len(parts) != 3 { | ||||
| 			if len(parts) != 4 { | ||||
| 				log.Println("Invalid decline button custom ID") | ||||
| 				return | ||||
| 			} | ||||
| @@ -385,6 +432,125 @@ func canCreateTicket(userName, softwareType string) bool { | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| func getTableNameAndBaseURL(choice string) (string, string) { | ||||
| 	var tableName, baseURL string | ||||
|  | ||||
| 	switch choice { | ||||
| 	case "vanity": | ||||
| 		tableName = "AuthUserData" | ||||
| 		baseURL = "http://vanitycheats.xyz/UserAuthentication.php" | ||||
| 	case "mesa": | ||||
| 		tableName = "AuthUserData-Mesachanger.com" | ||||
| 		baseURL = "http://mesachanger.com/UserAuthentication.php" | ||||
| 	default: | ||||
| 		fmt.Println("Invalid choice. Please choose 'vanity' or 'mesa'.") | ||||
| 	} | ||||
|  | ||||
| 	return tableName, baseURL | ||||
| } | ||||
|  | ||||
| func fetchUserID(username string, baseURL string) (int, error) { | ||||
| 	requestBody := &bytes.Buffer{} | ||||
| 	multiPartWriter := multipart.NewWriter(requestBody) | ||||
| 	err := multiPartWriter.WriteField("username", username) | ||||
| 	if err != nil { | ||||
| 		return 0, fmt.Errorf("error adding username field: %w", err) | ||||
| 	} | ||||
| 	multiPartWriter.Close() | ||||
| 	request, err := http.NewRequest("POST", baseURL, requestBody) | ||||
| 	if err != nil { | ||||
| 		return 0, fmt.Errorf("error creating request: %w", err) | ||||
| 	} | ||||
| 	request.Header.Set("Content-Type", multiPartWriter.FormDataContentType()) | ||||
| 	client := &http.Client{ | ||||
| 		Timeout: 10 * time.Second, | ||||
| 	} | ||||
| 	resp, err := client.Do(request) | ||||
| 	if err != nil { | ||||
| 		return 0, fmt.Errorf("error sending request: %w", err) | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
| 	var userResp UserResponse | ||||
| 	err = json.NewDecoder(resp.Body).Decode(&userResp) | ||||
| 	if err != nil { | ||||
| 		return 0, fmt.Errorf("error decoding JSON: %w", err) | ||||
| 	} | ||||
| 	uid, err := strconv.Atoi(userResp.ID) | ||||
| 	if err != nil { | ||||
| 		return 0, fmt.Errorf("error converting user ID: %w", err) | ||||
| 	} | ||||
| 	return uid, nil | ||||
| } | ||||
|  | ||||
| func resetHWID(tableName string, uids []int) { | ||||
| 	query := fmt.Sprintf(`UPDATE public.%q | ||||
| 		SET "StorageIdentifier" = NULL, "BootIdentifier" = NULL | ||||
| 		WHERE "UID" = ANY($1)`, tableName) | ||||
|  | ||||
| 	_, err := db.Exec(query, pq.Array(uids)) | ||||
| 	if err != nil { | ||||
| 		log.Printf("Error resetting HWID: %v", err) | ||||
| 		return | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func getIdentifiers(tableName string, uid int) { | ||||
| 	query := fmt.Sprintf(`SELECT "StorageIdentifier", "BootIdentifier" | ||||
| 		FROM public.%q | ||||
| 		WHERE "UID" = $1`, tableName) | ||||
|  | ||||
| 	var storageIdentifier, bootIdentifier sql.NullString | ||||
| 	err := db.QueryRow(query, uid).Scan(&storageIdentifier, &bootIdentifier) | ||||
| 	if err != nil { | ||||
| 		if err == sql.ErrNoRows { | ||||
| 			fmt.Println("HWID not set") | ||||
| 			return | ||||
| 		} | ||||
| 		fmt.Println("Error querying the database:", err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if !storageIdentifier.Valid { | ||||
| 		storageIdentifier = sql.NullString{String: "NULL", Valid: false} | ||||
| 	} | ||||
|  | ||||
| 	if !bootIdentifier.Valid { | ||||
| 		bootIdentifier = sql.NullString{String: "NULL", Valid: false} | ||||
| 	} | ||||
|  | ||||
| 	fmt.Printf("UID: %d, S: %s, B: %s\n", uid, storageIdentifier.String, bootIdentifier.String) | ||||
| } | ||||
|  | ||||
| func resetAndVerify(tableName string, uid int) (bool, error) { | ||||
| 	var beforeHash string | ||||
| 	err := db.QueryRow( | ||||
| 		fmt.Sprintf(`SELECT MD5(CONCAT("StorageIdentifier", "BootIdentifier")) FROM public.%q WHERE "UID" = $1`, tableName), | ||||
| 		uid, | ||||
| 	).Scan(&beforeHash) | ||||
| 	if err != nil { | ||||
| 		if err == sql.ErrNoRows { | ||||
| 			return false, fmt.Errorf("no rows found for UID %d", uid) | ||||
| 		} | ||||
| 		return false, fmt.Errorf("error querying database: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	resetHWID(tableName, []int{uid}) | ||||
|  | ||||
| 	var afterHash string | ||||
| 	err = db.QueryRow( | ||||
| 		fmt.Sprintf(`SELECT MD5(CONCAT("StorageIdentifier", "BootIdentifier")) FROM public.%q WHERE "UID" = $1`, tableName), | ||||
| 		uid, | ||||
| 	).Scan(&afterHash) | ||||
| 	if err != nil { | ||||
| 		if err == sql.ErrNoRows { | ||||
| 			return false, fmt.Errorf("no rows found for UID %d after reset", uid) | ||||
| 		} | ||||
| 		return false, fmt.Errorf("error querying database after reset: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	return beforeHash != afterHash, nil | ||||
| } | ||||
|  | ||||
| func main() { | ||||
| 	if client == nil { | ||||
| 		log.Println("Bot client is not initialized") | ||||
|   | ||||
		Reference in New Issue
	
	Block a user