-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'vinegarhq:master' into dgpu-prime
- Loading branch information
Showing
40 changed files
with
1,318 additions
and
264 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
package bloxstraprpc | ||
|
||
import ( | ||
"log" | ||
"regexp" | ||
"strings" | ||
"time" | ||
|
||
"github.com/hugolgst/rich-go/client" | ||
) | ||
|
||
const ( | ||
GameJoiningEntry = "[FLog::Output] ! Joining game" | ||
GameJoiningPrivateServerEntry = "[FLog::GameJoinUtil] GameJoinUtil::joinGamePostPrivateServer" | ||
GameJoiningReservedServerEntry = "[FLog::GameJoinUtil] GameJoinUtil::initiateTeleportToReservedServer" | ||
GameJoiningUDMUXEntry = "[FLog::Network] UDMUX Address = " | ||
GameJoinedEntry = "[FLog::Network] serverId:" | ||
GameDisconnectedEntry = "[FLog::Network] Time to disconnect replication data:" | ||
GameTeleportingEntry = "[FLog::SingleSurfaceApp] initiateTeleport" | ||
GameMessageEntry = "[FLog::Output] [BloxstrapRPC]" | ||
) | ||
|
||
var ( | ||
GameJoiningEntryPattern = regexp.MustCompile(`! Joining game '([0-9a-f\-]{36})' place ([0-9]+) at ([0-9\.]+)`) | ||
GameJoiningUDMUXPattern = regexp.MustCompile(`UDMUX Address = ([0-9\.]+), Port = [0-9]+ \| RCC Server Address = ([0-9\.]+), Port = [0-9]+`) | ||
GameJoinedEntryPattern = regexp.MustCompile(`serverId: ([0-9\.]+)\|[0-9]+`) | ||
) | ||
|
||
type ServerType int | ||
|
||
const ( | ||
Public ServerType = iota | ||
Private | ||
Reserved | ||
) | ||
|
||
type Activity struct { | ||
presence client.Activity | ||
timeStartedUniverse time.Time | ||
currentUniverseID string | ||
|
||
ingame bool | ||
teleported bool | ||
server ServerType | ||
placeID string | ||
jobID string | ||
mac string | ||
|
||
teleport bool | ||
reservedteleport bool | ||
} | ||
|
||
func (a *Activity) HandleRobloxLog(line string) error { | ||
if !a.ingame && a.placeID == "" { | ||
if strings.Contains(line, GameJoiningPrivateServerEntry) { | ||
a.server = Private | ||
return nil | ||
} | ||
|
||
if strings.Contains(line, GameJoiningEntry) { | ||
a.handleGameJoining(line) | ||
return nil | ||
} | ||
} | ||
|
||
if !a.ingame && a.placeID != "" { | ||
if strings.Contains(line, GameJoiningUDMUXEntry) { | ||
a.handleUDMUX(line) | ||
return nil | ||
} | ||
|
||
if strings.Contains(line, GameJoinedEntry) { | ||
a.handleGameJoined(line) | ||
return a.SetCurrentGame() | ||
} | ||
} | ||
|
||
if a.ingame && a.placeID != "" { | ||
if strings.Contains(line, GameDisconnectedEntry) { | ||
log.Printf("Disconnected From Game (%s/%s/%s)", a.placeID, a.jobID, a.mac) | ||
a.Clear() | ||
return a.SetCurrentGame() | ||
} | ||
|
||
if strings.Contains(line, GameTeleportingEntry) { | ||
log.Printf("Teleporting to server (%s/%s/%s)", a.placeID, a.jobID, a.mac) | ||
a.teleport = true | ||
return nil | ||
} | ||
|
||
if a.teleport && strings.Contains(line, GameJoiningReservedServerEntry) { | ||
log.Printf("Teleporting to reserved server") | ||
a.reservedteleport = true | ||
return nil | ||
} | ||
|
||
if strings.Contains(line, GameMessageEntry) { | ||
m, err := ParseMessage(line) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
a.ProcessMessage(&m) | ||
return a.UpdatePresence() | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (a *Activity) handleUDMUX(line string) { | ||
m := GameJoiningUDMUXPattern.FindStringSubmatch(line) | ||
if len(m) != 3 || m[2] != a.mac { | ||
return | ||
} | ||
|
||
a.mac = m[1] | ||
log.Printf("Got game join UDMUX: %s", a.mac) | ||
} | ||
|
||
func (a *Activity) handleGameJoining(line string) { | ||
m := GameJoiningEntryPattern.FindStringSubmatch(line) | ||
if len(m) != 4 { | ||
return | ||
} | ||
|
||
a.ingame = false | ||
a.jobID = m[1] | ||
a.placeID = m[2] | ||
a.mac = m[3] | ||
|
||
if a.teleport { | ||
a.teleported = true | ||
a.teleport = false | ||
} | ||
|
||
if a.reservedteleport { | ||
a.server = Reserved | ||
a.reservedteleport = false | ||
} | ||
|
||
log.Printf("Joining Game (%s/%s/%s)", a.jobID, a.placeID, a.mac) | ||
} | ||
|
||
func (a *Activity) handleGameJoined(line string) { | ||
m := GameJoinedEntryPattern.FindStringSubmatch(line) | ||
if len(m) != 2 || m[1] != a.mac { | ||
return | ||
} | ||
|
||
a.ingame = true | ||
log.Printf("Joined Game (%s/%s/%s)", a.placeID, a.jobID, a.mac) | ||
// handle rpc | ||
} | ||
|
||
func (a *Activity) Clear() { | ||
a.teleported = false | ||
a.ingame = false | ||
a.placeID = "" | ||
a.jobID = "" | ||
a.mac = "" | ||
a.server = Public | ||
a.presence = client.Activity{} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
package bloxstraprpc | ||
|
||
import ( | ||
"log" | ||
"strconv" | ||
"time" | ||
|
||
"github.com/hugolgst/rich-go/client" | ||
"github.com/vinegarhq/vinegar/roblox/api" | ||
) | ||
|
||
// This is Bloxstrap's Discord RPC application ID. | ||
const RPCAppID = "1005469189907173486" | ||
|
||
func Login() error { | ||
log.Println("Authenticating Discord RPC") | ||
return client.Login(RPCAppID) | ||
} | ||
|
||
func Logout() { | ||
log.Println("Deauthenticating Discord RPC") | ||
client.Logout() | ||
} | ||
|
||
func (a *Activity) SetCurrentGame() error { | ||
if !a.ingame { | ||
log.Println("Not in game, clearing presence") | ||
a.presence = client.Activity{} | ||
} else { | ||
if err := a.SetPresence(); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return a.UpdatePresence() | ||
} | ||
|
||
func (a *Activity) SetPresence() error { | ||
var status string | ||
log.Printf("Setting presence for Place ID %s", a.placeID) | ||
|
||
uid, err := api.GetUniverseID(a.placeID) | ||
if err != nil { | ||
return err | ||
} | ||
log.Printf("Got Universe ID as %s", uid) | ||
|
||
if !a.teleported || uid != a.currentUniverseID { | ||
a.timeStartedUniverse = time.Now() | ||
} | ||
|
||
a.currentUniverseID = uid | ||
|
||
gd, err := api.GetGameDetails(uid) | ||
if err != nil { | ||
return err | ||
} | ||
log.Println("Got Game details") | ||
|
||
tn, err := api.GetGameIcon(uid, "PlaceHolder", "512x512", "Png", false) | ||
if err != nil { | ||
return err | ||
} | ||
log.Printf("Got Universe thumbnail as %s", tn.ImageURL) | ||
|
||
switch a.server { | ||
case Public: | ||
status = "by " + gd.Creator.Name | ||
case Private: | ||
status = "In a private server" | ||
case Reserved: | ||
status = "In a reserved server" | ||
} | ||
|
||
a.presence = client.Activity{ | ||
State: status, | ||
Details: "Playing " + gd.Name, | ||
LargeImage: tn.ImageURL, | ||
LargeText: gd.Name, | ||
SmallImage: "roblox", | ||
SmallText: "Roblox", | ||
Timestamps: &client.Timestamps{ | ||
Start: &a.timeStartedUniverse, | ||
}, | ||
Buttons: []*client.Button{ | ||
{ | ||
Label: "See game page", | ||
Url: "https://www.roblox.com/games/" + a.placeID, | ||
}, | ||
}, | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (a *Activity) ProcessMessage(m *Message) { | ||
if m.Command != "SetRichPresence" { | ||
return | ||
} | ||
|
||
if m.Data.Details != "" { | ||
a.presence.Details = m.Data.Details | ||
} | ||
|
||
if m.Data.State != "" { | ||
a.presence.State = m.Data.State | ||
} | ||
|
||
if a.presence.Timestamps != nil { | ||
if m.TimestampStart == 0 { | ||
a.presence.Timestamps.Start = nil | ||
} else { | ||
ts := time.UnixMilli(m.TimestampStart) | ||
a.presence.Timestamps.Start = &ts | ||
} | ||
} | ||
|
||
if a.presence.Timestamps != nil { | ||
if m.TimestampEnd == 0 { | ||
a.presence.Timestamps.End = nil | ||
} else { | ||
te := time.UnixMilli(m.TimestampEnd) | ||
a.presence.Timestamps.End = &te | ||
} | ||
} | ||
|
||
if m.SmallImage.Clear { | ||
a.presence.SmallImage = "" | ||
} | ||
|
||
if m.SmallImage.AssetID != 0 { | ||
a.presence.SmallImage = "https://assetdelivery.roblox.com/v1/asset/?id" + | ||
strconv.FormatInt(m.SmallImage.AssetID, 10) | ||
} | ||
|
||
if m.LargeImage.Clear { | ||
a.presence.LargeImage = "" | ||
} | ||
|
||
if m.LargeImage.AssetID != 0 { | ||
a.presence.LargeImage = "https://assetdelivery.roblox.com/v1/asset/?id" + | ||
strconv.FormatInt(m.LargeImage.AssetID, 10) | ||
} | ||
} | ||
|
||
func (a *Activity) UpdatePresence() error { | ||
// if a.presence == client.Activity{} { | ||
// log.Println("Presence is empty, clearing") | ||
// return ClearPresence() | ||
// } | ||
|
||
log.Printf("Updating presence: %+v", a.presence) | ||
return client.SetActivity(a.presence) | ||
} |
Oops, something went wrong.