|
2 | 2 | package studiorpc |
3 | 3 |
|
4 | 4 | import ( |
5 | | - "fmt" |
6 | 5 | "log/slog" |
7 | | - "regexp" |
8 | 6 | "strconv" |
9 | 7 | "strings" |
| 8 | + "time" |
10 | 9 |
|
11 | 10 | "github.com/altfoxie/drpc" |
12 | 11 | "github.com/sewnie/rbxweb" |
13 | 12 | ) |
14 | 13 |
|
15 | 14 | const appID = "1159891020956323923" |
16 | 15 |
|
17 | | -const ( |
18 | | - gameOpenEntry = "[FLog::LifecycleManager] Entered PlaceSessionScope:" |
19 | | - gameCloseEntry = "[FLog::LifecycleManager] Exited PlaceSessionScope:" |
20 | | -) |
21 | | - |
22 | | -var gameOpenEntryPattern = regexp.MustCompile(`Entered PlaceSessionScope:'([0-9]+)'`) |
23 | | - |
24 | 16 | type StudioRPC struct { |
25 | 17 | presence drpc.Activity |
26 | 18 | client *drpc.Client |
27 | 19 | rbx *rbxweb.Client |
28 | 20 |
|
29 | | - placeID rbxweb.PlaceID |
| 21 | + place *rbxweb.PlaceDetail |
30 | 22 | } |
31 | 23 |
|
32 | | -func New() *StudioRPC { |
33 | | - c, _ := drpc.New("1159891020956323923") |
| 24 | +func New(c *rbxweb.Client) *StudioRPC { |
34 | 25 | return &StudioRPC{ |
35 | | - client: c, |
36 | | - rbx: rbxweb.NewClient(), |
| 26 | + client: drpc.New("1159891020956323923"), |
| 27 | + rbx: c, |
| 28 | + presence: drpc.Activity{ |
| 29 | + Assets: &drpc.Assets{ |
| 30 | + LargeImage: "studio", |
| 31 | + LargeText: "Vinegar", |
| 32 | + }, |
| 33 | + }, |
37 | 34 | } |
38 | 35 | } |
39 | 36 |
|
40 | | -// Handle implements the BinaryRichPresence interface |
41 | 37 | func (s *StudioRPC) Handle(line string) error { |
42 | | - if strings.Contains(line, gameOpenEntry) { |
43 | | - return s.handleGameOpen(line) |
44 | | - } else if strings.Contains(line, gameCloseEntry) { |
45 | | - return s.handleGameClose() |
| 38 | + for _, handler := range []func(string) error{ |
| 39 | + s.handleOpen, |
| 40 | + s.handleEdit, |
| 41 | + } { |
| 42 | + if err := handler(line); err != nil { |
| 43 | + return err |
| 44 | + } |
46 | 45 | } |
47 | 46 |
|
48 | 47 | return nil |
49 | 48 | } |
50 | 49 |
|
51 | | -func (s *StudioRPC) handleGameOpen(line string) error { |
52 | | - m := gameOpenEntryPattern.FindStringSubmatch(line) |
53 | | - if len(m) != 2 { |
54 | | - return fmt.Errorf("log game join report entry is invalid") |
| 50 | +func (s *StudioRPC) handleOpen(line string) error { |
| 51 | + const entry = "[FLog::StudioKeyEvents] open place (identifier = " |
| 52 | + if !strings.HasPrefix(line, entry) { |
| 53 | + return nil |
55 | 54 | } |
56 | 55 |
|
57 | | - pid, err := strconv.ParseInt(m[1], 10, 64) |
| 56 | + // open place (identifier = $id) [start] |
| 57 | + i, err := strconv.ParseInt(line[len(entry):len(line)-len(") [start]")], 10, 64) |
58 | 58 | if err != nil { |
59 | 59 | return err |
60 | 60 | } |
| 61 | + place := rbxweb.PlaceID(i) |
61 | 62 |
|
62 | | - s.placeID = rbxweb.PlaceID(pid) |
| 63 | + slog.Info("studiorpc: Opened Place", "placeid", i) |
63 | 64 |
|
64 | | - slog.Info("Handled GameOpen", "placeid", s.placeID) |
| 65 | + s.place, err = s.rbx.GamesV1.GetPlaceDetail(place) |
| 66 | + if err != nil { |
| 67 | + slog.Error("studiorpc: Failed to fetch place detail", "err", err) |
| 68 | + } |
65 | 69 |
|
66 | | - return s.UpdateGamePresence() |
67 | | -} |
| 70 | + s.presence.Timestamps = &drpc.Timestamps{ |
| 71 | + Start: time.Now(), |
| 72 | + } |
68 | 73 |
|
69 | | -func (s *StudioRPC) handleGameClose() error { |
70 | | - s.presence = drpc.Activity{} |
71 | | - s.placeID = rbxweb.PlaceID(0) |
| 74 | + return nil |
| 75 | +} |
72 | 76 |
|
73 | | - slog.Info("Handled GameClose") |
| 77 | +func (s *StudioRPC) handleEdit(line string) error { |
| 78 | + const entry = "[FLog::RobloxDocManager] Setting current doc to type " |
| 79 | + if !strings.HasPrefix(line, entry) { |
| 80 | + return nil |
| 81 | + } |
| 82 | + slog.Info("studiorpc: Changed main view") |
| 83 | + switch line[len(entry):] { |
| 84 | + case "-1": |
| 85 | + s.place = nil |
| 86 | + s.presence.Details = "Idling" |
| 87 | + s.presence.State = "" |
| 88 | + s.presence.Assets.SmallImage = "" |
| 89 | + s.presence.Timestamps = &drpc.Timestamps{ |
| 90 | + Start: time.Now(), |
| 91 | + } |
| 92 | + case "0": |
| 93 | + s.presence.Details = "Developing a place" |
| 94 | + s.presence.State = "" |
| 95 | + s.presence.Assets.SmallImage = "place" |
| 96 | + if s.place != nil { |
| 97 | + s.presence.Details = "Developing " + s.place.Name |
| 98 | + } |
| 99 | + case "2": |
| 100 | + s.presence.State = "Editing Script" |
| 101 | + s.presence.Assets.SmallImage = "script" |
| 102 | + } |
74 | 103 |
|
75 | 104 | return s.client.SetActivity(s.presence) |
76 | 105 | } |
0 commit comments