Guest User

offensive

a guest
Oct 15th, 2016
30
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JSON 8.14 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "bufio"
  5.     "encoding/json"
  6.     "encoding/xml"
  7.     "flag"
  8.     "fmt"
  9.     "github.com/anaminus/rbxauth"
  10.     "golang.org/x/crypto/ssh/terminal"
  11.     "io/ioutil"
  12.     "net/url"
  13.     "os"
  14.     "os/exec"
  15.     "path/filepath"
  16.     "sort"
  17.     "strconv"
  18.     "strings"
  19.     "syscall"
  20. )
  21.  
  22. var AllUsers = filepath.Join(programFiles(), `Roblox\Versions`)
  23. var CurrentUser = filepath.Join(programFiles(), `Roblox\Versions`)
  24. var Executables = []string{"RobloxPlayerBeta.exe"}
  25.  
  26. func localAppData() string {
  27.     lappdata := os.Getenv("LOCALAPPDATA")
  28.     if _, err := os.Stat(lappdata); lappdata == "" || err != nil {
  29.         userProfile := os.Getenv("USERPROFILE")
  30.         lappdata = filepath.Join(userProfile, `AppData\Local`)
  31.         if _, err := os.Stat(lappdata); lappdata == "" || err != nil {
  32.             lappdata = filepath.Join(userProfile, `Local Settings\Application Data`)
  33.         }
  34.     }
  35.     return lappdata
  36. }
  37.  
  38. func programFiles() string {
  39.     programFiles := `C:\Users\0610063319\OneDrive\Documents`
  40.     if _, err := os.Stat(programFiles); err != nil {
  41.         programFiles = `C:\Users\0610063319\OneDrive\Documents`
  42.     }
  43.     return programFiles
  44. }
  45.  
  46. func findBuild(dirname string) string {
  47.     if _, err := os.Stat(dirname); err != nil {
  48.         return ""
  49.     }
  50.  
  51.     files, err := ioutil.ReadDir(dirname)
  52.     if err != nil {
  53.         return ""
  54.     }
  55.     for _, file := range files {
  56.         if file.IsDir() {
  57.             for _, exe := range Executables {
  58.                 exepath := filepath.Join(dirname, file.Name(), exe)
  59.                 if _, err := os.Stat(exepath); err == nil {
  60.                     return exepath
  61.                 }
  62.             }
  63.         }
  64.     }
  65.     return ""
  66. }
  67.  
  68. func FindPlayer() (build, host string) {
  69.     build = findBuild(AllUsers)
  70.     if build == "" {
  71.         build = findBuild(CurrentUser)
  72.     }
  73.     if build == "" {
  74.         return
  75.     }
  76.  
  77.     type AppSettings struct {
  78.         BaseUrl string
  79.     }
  80.  
  81.     b, err := ioutil.ReadFile(filepath.Join(filepath.Dir(build), "AppSettings.xml"))
  82.     if err != nil {
  83.         return
  84.     }
  85.     appSettings := AppSettings{}
  86.     err = xml.Unmarshal(b, &appSettings)
  87.     u, _ := url.Parse(appSettings.BaseUrl)
  88.     if u == nil {
  89.         return
  90.     }
  91.     host = u.Host
  92.     return
  93. }
  94.  
  95. type GameRequest struct {
  96.     JobId                string `json:"jobId"`
  97.     Status               int    `json:"status"`
  98.     JoinScriptURL        string `json:"joinScriptUrl"`
  99.     AuthenticationURL    string `json:"authenticationUrl"`
  100.     AuthenticationTicket string `json:"authenticationTicket"`
  101. }
  102.  
  103. type State struct {
  104.     Client *rbxauth.Client
  105.     Player string
  106.     Host   string
  107. }
  108.  
  109. func (state *State) Message(format string, v ...interface{}) {
  110.     fmt.Fprintf(os.Stderr, format, v...)
  111. }
  112.  
  113. func (state *State) Login(username string) bool {
  114.     var password []byte
  115.     var err error
  116.     state.Message("Enter your password: ")
  117.     password, err = terminal.ReadPassword(int(syscall.Stdin))
  118.     state.Message("\n")
  119.     if err != nil {
  120.         state.Message("failed to read password: %s\n", err)
  121.         return false
  122.     }
  123.     if err := state.Client.Login(state.Host, username, password); err != nil {
  124.         if err == rbxauth.ErrLoggedIn {
  125.             state.Message("%s\n", err)
  126.         } else {
  127.             state.Message("failed to log in: %s\n", err)
  128.         }
  129.         return false
  130.     }
  131.     return true
  132. }
  133.  
  134. func (state *State) Logout() {
  135.     state.Client.Logout(state.Host)
  136. }
  137.  
  138. func (state *State) Join(placeID int) {
  139.     gr := GameRequest{}
  140.     {
  141.         launchURL := &url.URL{
  142.             Scheme: "https",
  143.             Host:   state.Host,
  144.             Path:   "/game/placelauncher.ashx",
  145.             RawQuery: url.Values{
  146.                 "placeId":       []string{strconv.Itoa(placeID)},
  147.                                 "request":       []string{"RequestGame"},
  148.             }.Encode(),
  149.         }
  150.         resp, err := state.Client.Get(launchURL.String())
  151.         if err != nil {
  152.             state.Message("failed to request game: %s\n", err)
  153.             return
  154.         }
  155.         jd := json.NewDecoder(resp.Body)
  156.         if err := jd.Decode(&gr); err != nil {
  157.                         state.Message("ERROR: " + err.Error())
  158.             state.Message("failed to decode response: %s\n", err)
  159.             resp.Body.Close()
  160.             return
  161.         }
  162.         resp.Body.Close()
  163.  
  164.         // TODO: may be necessary to check job status:
  165.         // ?request=CheckGameJobStatus&jobId=JoinPlace%3D[id]%3B
  166.     }
  167.  
  168.     // Launch game client.
  169.     {
  170.         err := exec.Command(state.Player,
  171.             "--play",
  172.             "-a", gr.AuthenticationURL,
  173.             "-t", gr.AuthenticationTicket,
  174.             "-j", gr.JoinScriptURL,
  175.         ).Start()
  176.         if err != nil {
  177.             state.Message("failed to start game client: %s\n", err)
  178.             return
  179.         }
  180.     }
  181. }
  182.  
  183. func (state *State) Help(cmds Commands, arg string) {
  184.     if arg == "" {
  185.         state.Message("Commands:\n")
  186.         sorted := make([]string, len(cmds))
  187.         {
  188.             i := 0
  189.             for name := range cmds {
  190.                 sorted[i] = name
  191.                 i++
  192.             }
  193.         }
  194.         sort.Strings(sorted)
  195.  
  196.         for _, name := range sorted {
  197.             cmd := cmds[name]
  198.             state.Message("\t%s\t%s\n", name, cmd.Summ)
  199.         }
  200.         return
  201.     }
  202.  
  203.     if arg == "help" {
  204.         state.Message("help [command]\n\tDisplay all commands, or details for a specific command.\n")
  205.         return
  206.     }
  207.  
  208.     cmd, ok := cmds[arg]
  209.     if !ok {
  210.         state.Message("Unknown command %q\n", arg)
  211.         return
  212.     }
  213.  
  214.     if cmd.Args == "" {
  215.         state.Message("%s\n\t%s\n", arg, cmd.Desc)
  216.     } else {
  217.         desc := strings.Replace(cmd.Desc, "\n", "\n\t", -1)
  218.         state.Message("%s %s\n\t%s\n", arg, cmd.Args, desc)
  219.     }
  220. }
  221.  
  222. func InteractiveMode(state *State, cmds Commands) {
  223.     input := bufio.NewReader(os.Stdin)
  224.     for {
  225.         state.Message("\nrbxlaunch>")
  226.         line, _ := input.ReadString('\n')
  227.         line = strings.TrimSpace(line)
  228.         i := strings.Index(line, " ")
  229.         var name, arg string
  230.         if i == -1 {
  231.             name = line
  232.         } else {
  233.             name, arg = line[:i], strings.TrimSpace(line[i+1:])
  234.         }
  235.  
  236.         if name == "" {
  237.             continue
  238.         }
  239.  
  240.         if name == "help" {
  241.             state.Help(cmds, arg)
  242.             continue
  243.         }
  244.  
  245.         cmd, ok := cmds[name]
  246.         if !ok {
  247.             state.Message("Unknown command %q. Type \"help\" for a list of commands.\n", name)
  248.             continue
  249.         }
  250.  
  251.         switch cmd.Func(state, arg) {
  252.         case -1:
  253.             // exit
  254.             return
  255.         case 0:
  256.             // success
  257.         case 1:
  258.             // failure
  259.         }
  260.     }
  261. }
  262.  
  263. type Commands map[string]Command
  264.  
  265. type Command struct {
  266.     Args string
  267.     Summ string
  268.     Desc string
  269.     Func func(state *State, arg string) int
  270. }
  271.  
  272. func main() {
  273.     var interactive bool
  274.     var username string
  275.     var placeID int
  276.  
  277.     // Parse flags.
  278.     flag.BoolVar(&interactive, "i", false, "Force interactive mode.")
  279.     flag.StringVar(&username, "u", "", "Username to login with.")
  280.     flag.IntVar(&placeID, "id", 0, "ID of place to join.")
  281.     flag.Parse()
  282.  
  283.     if len(os.Args) < 2 {
  284.         interactive = true
  285.     }
  286.  
  287.     state := &State{Client: &rbxauth.Client{}}
  288.  
  289.     // Find game client.
  290.     state.Player, state.Host = FindPlayer()
  291.     if state.Player == "" {
  292.         state.Message("failed to locate game client. Make sure Roblox is installed.\n")
  293.         return
  294.     }
  295.  
  296.     if username != "" {
  297.         if !state.Login(username) {
  298.             return
  299.         }
  300.     }
  301.  
  302.     if interactive {
  303.         InteractiveMode(state, Commands{
  304.             "exit": Command{
  305.                 Args: "",
  306.                 Summ: "Terminate the program.",
  307.                 Desc: "Terminate the program.",
  308.                 Func: func(state *State, arg string) int {
  309.                     return -1
  310.                 },
  311.             },
  312.             "login": Command{
  313.                 Args: "USERNAME",
  314.                 Summ: "Login to a user account.",
  315.                 Desc: "Login to the account of the given username.\nYou will be prompted to enter the account's password.\nThe user session persists until the program terminates.",
  316.                 Func: func(state *State, username string) int {
  317.                     if username == "" {
  318.                         state.Message("username required.\n")
  319.                         return 1
  320.                     }
  321.                     state.Login(username)
  322.                     return 0
  323.                 },
  324.             },
  325.             "logout": Command{
  326.                 Args: "",
  327.                 Summ: "Logout the current user.",
  328.                 Desc: "Logout the current user.",
  329.                 Func: func(state *State, arg string) int {
  330.                     state.Logout()
  331.                     return 0
  332.                 },
  333.             },
  334.             "join": Command{
  335.                 Args: "ID",
  336.                 Summ: "Join a place.",
  337.                 // Desc: "Join place `ID`.\nIf `JOB` is given, the program attempts to join the associated server.\nIf you are not logged in, you will join as a guest.",
  338.                 Desc: "Join the place of the given ID.\nIf you have not logged in, then you will join as a guest.",
  339.                 Func: func(state *State, arg string) int {
  340.                     var placeID int
  341.                     fmt.Sscan(arg, &placeID)
  342.                     if placeID == 0 {
  343.                         state.Message("valid place ID required.")
  344.                         return 1
  345.                     }
  346.                     state.Join(placeID)
  347.                     return 0
  348.                 },
  349.             },
  350.         })
  351.         return
  352.     }
  353.  
  354.     if placeID == 0 {
  355.         state.Message("place ID required (-id).\n")
  356.         return
  357.     }
  358.  
  359.     // Request game.
  360.     state.Join(placeID)
  361. }
Add Comment
Please, Sign In to add comment