Compare commits
	
		
			6 Commits
		
	
	
		
			ImplDiscor
			...
			fa254c60f7
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						
						
							
						
						fa254c60f7
	
				 | 
					
					
						|||
| 
						
						
							
						
						00db797d65
	
				 | 
					
					
						|||
| 
						
						
							
						
						8b001e499a
	
				 | 
					
					
						|||
| 
						
						
							
						
						62faa6c974
	
				 | 
					
					
						|||
| 
						
						
							
						
						2a42301c25
	
				 | 
					
					
						|||
| 7eebc01816 | 
@@ -3,6 +3,7 @@ token = ""
 | 
			
		||||
appid = ""
 | 
			
		||||
guildid = ""
 | 
			
		||||
category_id = ""
 | 
			
		||||
admin_roles = [""]
 | 
			
		||||
 | 
			
		||||
[database]
 | 
			
		||||
host = ""
 | 
			
		||||
@@ -11,4 +12,4 @@ name = ""
 | 
			
		||||
username = ""
 | 
			
		||||
password = ""
 | 
			
		||||
 | 
			
		||||
admin_roles = [""]
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										208
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										208
									
								
								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 {
 | 
			
		||||
@@ -108,12 +125,11 @@ func getUsernameFromMember(member *discordgo.Member) string {
 | 
			
		||||
	} else if member.User != nil && member.User.Username != "" {
 | 
			
		||||
		userName = member.User.Username
 | 
			
		||||
	} else {
 | 
			
		||||
		userName = "UnknownUser" 
 | 
			
		||||
		userName = "UnknownUser"
 | 
			
		||||
	}
 | 
			
		||||
	return userName
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	commands = []discordgo.ApplicationCommand{
 | 
			
		||||
		{
 | 
			
		||||
@@ -224,15 +240,31 @@ 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,
 | 
			
		||||
				ParentID: categoryID,
 | 
			
		||||
				PermissionOverwrites: []*discordgo.PermissionOverwrite{
 | 
			
		||||
					{
 | 
			
		||||
						ID:    guildID,
 | 
			
		||||
						Type:  discordgo.PermissionOverwriteTypeRole,
 | 
			
		||||
						Deny:  discordgo.PermissionViewChannel,
 | 
			
		||||
						ID:   guildID,
 | 
			
		||||
						Type: discordgo.PermissionOverwriteTypeRole,
 | 
			
		||||
						Deny: discordgo.PermissionViewChannel,
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			})
 | 
			
		||||
@@ -241,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{
 | 
			
		||||
@@ -265,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),
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
@@ -284,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 {
 | 
			
		||||
@@ -299,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,
 | 
			
		||||
@@ -331,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
 | 
			
		||||
			}
 | 
			
		||||
@@ -375,10 +421,10 @@ func canCreateTicket(userName, softwareType string) bool {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, channel := range guildChannels {
 | 
			
		||||
		if channel.Type == discordgo.ChannelTypeGuildText && channel.ParentID == config.Discord.CategoryID {	
 | 
			
		||||
		if channel.Type == discordgo.ChannelTypeGuildText && channel.ParentID == config.Discord.CategoryID {
 | 
			
		||||
			expectedName := fmt.Sprintf("reset-%s-%s", softwareType, userName)
 | 
			
		||||
			if channel.Name == expectedName {
 | 
			
		||||
				return false 
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -386,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")
 | 
			
		||||
@@ -441,4 +606,3 @@ func main() {
 | 
			
		||||
		db.Close()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user