You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
282 lines
6.5 KiB
282 lines
6.5 KiB
// Package altvr contains functions used to
|
|
// interface with the AltspaceVR API
|
|
package altvr
|
|
|
|
import (
|
|
"log"
|
|
"net/http/cookiejar"
|
|
|
|
"golang.org/x/net/publicsuffix"
|
|
)
|
|
|
|
// AltVR Is the main ASVR client type
|
|
type AltVR struct {
|
|
jar *cookiejar.Jar
|
|
username string
|
|
password string
|
|
csrfToken string // CSRF token for requests
|
|
userID string // Our own user id
|
|
user User // Cache of our own user data
|
|
friends []User
|
|
friendships []Friendship
|
|
onlineFriendships []Friendship
|
|
}
|
|
|
|
// DisconnectFunc handler for disconnection
|
|
type DisconnectFunc func(User)
|
|
|
|
// ConnectFunc handler for connection
|
|
type ConnectFunc func(User)
|
|
|
|
// New creates a new instance of the AltVR client
|
|
// Takes an account username and password as parameters
|
|
func New(u, p string) AltVR {
|
|
avr := AltVR{username: u, password: p}
|
|
var err error
|
|
avr.jar, err = cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
err = avr.doLogin()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
log.Println("AVR Logged in")
|
|
user, err := avr.fetchMyUser()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
avr.user = user
|
|
if err := avr.FetchFriendships(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
log.Println("AVR Ready")
|
|
return avr
|
|
}
|
|
|
|
// GetAvatarURL returns the cached user avatar url
|
|
func (avr *AltVR) GetAvatarURL() string {
|
|
return avr.user.ProfileImage
|
|
}
|
|
|
|
// FetchMyUser fetches our own user data and cache it
|
|
func (avr *AltVR) FetchMyUser() error {
|
|
user, err := avr.fetchMyUser()
|
|
|
|
if err == errorLogin {
|
|
log.Println("Not logged in, doing login")
|
|
err = avr.doLogin()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
user, err = avr.fetchMyUser()
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
avr.user = user
|
|
return nil
|
|
}
|
|
|
|
// GetMyUser Returns the cached copy of our user data
|
|
func (avr *AltVR) GetMyUser() User {
|
|
return avr.user
|
|
}
|
|
|
|
// FetchClientIP retrives the client IP from the API
|
|
func (avr *AltVR) FetchClientIP() (string, error) {
|
|
return avr.fetchClientIP()
|
|
}
|
|
|
|
// FetchFriendships fetches all our friends' user data and caches it
|
|
func (avr *AltVR) FetchFriendships() error {
|
|
var err error
|
|
friendships, err := avr.fetchFriendships()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, friendship := range friendships {
|
|
found := false
|
|
for _, ff := range avr.friendships {
|
|
if friendship.FriendID == ff.FriendID {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
if err := avr.FetchFriend(friendship.FriendID); err != nil {
|
|
log.Printf("Error fetching friend user data: %+v\n", err)
|
|
}
|
|
}
|
|
}
|
|
avr.friendships = friendships
|
|
return nil
|
|
}
|
|
|
|
// GetFriendships returns the cached list of friendships
|
|
func (avr *AltVR) GetFriendships() []Friendship {
|
|
return avr.friendships
|
|
}
|
|
|
|
// FetchOnlineFriendships check for changes in the online friends list
|
|
// Triggers the callback functions on dis/connect
|
|
func (avr *AltVR) FetchOnlineFriendships(cfn ConnectFunc, dfn DisconnectFunc) error {
|
|
friendships, err := avr.fetchFriendshipsOnline()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, friendship := range friendships {
|
|
found := false
|
|
for _, of := range avr.onlineFriendships {
|
|
if friendship.FriendID == of.FriendID {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
if err := avr.FetchFriend(friendship.FriendID); err != nil {
|
|
return err
|
|
}
|
|
cfn(avr.GetFriend(friendship.FriendID))
|
|
}
|
|
}
|
|
|
|
for _, friendship := range avr.onlineFriendships {
|
|
found := false
|
|
for _, of := range friendships {
|
|
if friendship.FriendID == of.FriendID {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
if err := avr.FetchFriend(friendship.FriendID); err != nil {
|
|
return err
|
|
}
|
|
dfn(avr.GetFriend(friendship.FriendID))
|
|
}
|
|
}
|
|
|
|
avr.onlineFriendships = friendships
|
|
return nil
|
|
}
|
|
|
|
// FetchFriend fetches one user's data and update the cache
|
|
func (avr *AltVR) FetchFriend(userID string) error {
|
|
users, err := avr.fetchUsers(userID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
user := users[0]
|
|
found := false
|
|
for k, u := range avr.friends {
|
|
if u.UserID == user.UserID {
|
|
avr.friends[k] = user
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
avr.friends = append(avr.friends, user)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// FetchFriends fetches many users' data and update the cache
|
|
func (avr *AltVR) FetchFriends(userID ...string) error {
|
|
users, err := avr.fetchUsers(userID...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, user := range users {
|
|
found := false
|
|
for k, u := range avr.friends {
|
|
if u.UserID == user.UserID {
|
|
avr.friends[k] = user
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
avr.friends = append(avr.friends, user)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetFriend gets a cached friend user data with the user ID
|
|
func (avr *AltVR) GetFriend(userID string) User {
|
|
var user User
|
|
for _, u := range avr.friends {
|
|
if u.UserID == userID {
|
|
user = u
|
|
break
|
|
}
|
|
}
|
|
return user
|
|
}
|
|
|
|
// GetFriendByUsername gets a cached friend user data with the username
|
|
func (avr *AltVR) GetFriendByUsername(username string) User {
|
|
var user User
|
|
for _, u := range avr.friends {
|
|
if u.Username == username {
|
|
user = u
|
|
break
|
|
}
|
|
}
|
|
return user
|
|
}
|
|
|
|
// FetchPendingFriendshipRequests fetches a list of pending friendship requests
|
|
func (avr *AltVR) FetchPendingFriendshipRequests() ([]Friendship, error) {
|
|
fr, err := avr.fetchPendingFriendshipRequests()
|
|
if err != nil {
|
|
log.Printf("Error fetching pending conversations: %+v\n", err)
|
|
return fr, err
|
|
}
|
|
var uids []string
|
|
for _, ff := range fr {
|
|
uids = append(uids, ff.UserID)
|
|
}
|
|
avr.FetchFriends(uids...)
|
|
return fr, nil
|
|
}
|
|
|
|
// AcceptFriendshipRequest accepts a pending friendship request
|
|
func (avr *AltVR) AcceptFriendshipRequest(FriendshipID string) error {
|
|
return avr.acceptPendingFriendshipRequest(FriendshipID)
|
|
}
|
|
|
|
// DenyFriendshipRequest accepts a pending friendship request
|
|
func (avr *AltVR) DenyFriendshipRequest(FriendshipID string) error {
|
|
return avr.denyPendingFriendshipRequest(FriendshipID)
|
|
}
|
|
|
|
// FetchPendingConversations fetches any pending conversations
|
|
func (avr *AltVR) FetchPendingConversations() ([]Conversation, error) {
|
|
pc, err := avr.fetchPendingConversations()
|
|
if err != nil {
|
|
log.Printf("Error fetching pending conversations: %+v\n", err)
|
|
return pc, err
|
|
}
|
|
var ccs []Conversation
|
|
for _, c := range pc {
|
|
if !c.IsRead {
|
|
ccs = append(ccs, c)
|
|
}
|
|
}
|
|
return ccs, nil
|
|
}
|
|
|
|
// AcknowkledgeConversation mark a conversation item as read
|
|
func (avr *AltVR) AcknowkledgeConversation(conversationID string) error {
|
|
return avr.markConversationAsRead(conversationID)
|
|
}
|
|
|
|
// PostNewConversation send a new message
|
|
func (avr *AltVR) PostNewConversation(userID, message string) error {
|
|
return avr.postNewConversation(userID, message)
|
|
}
|