Add vendor
This commit is contained in:
parent
4147e7c9de
commit
59f81fa7c6
2
vendor/git.itzana.me/itzaname/go-roblox/.gitignore
generated
vendored
Normal file
2
vendor/git.itzana.me/itzaname/go-roblox/.gitignore
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.vscode/launch.json
|
||||||
|
debug
|
1
vendor/git.itzana.me/itzaname/go-roblox/README.md
generated
vendored
Normal file
1
vendor/git.itzana.me/itzaname/go-roblox/README.md
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
Copyright © Stuart Livingston
|
110
vendor/git.itzana.me/itzaname/go-roblox/asset.go
generated
vendored
Normal file
110
vendor/git.itzana.me/itzaname/go-roblox/asset.go
generated
vendored
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
package roblox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AssetUploadOptions struct {
|
||||||
|
Name string
|
||||||
|
AssetID int
|
||||||
|
Description string
|
||||||
|
Public bool
|
||||||
|
Comments bool
|
||||||
|
Group int
|
||||||
|
}
|
||||||
|
|
||||||
|
type AssetUploadResponse struct {
|
||||||
|
AssetID int64 `json:"AssetId"`
|
||||||
|
AssetVersionID int64 `json:"AssetVersionId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Session) CreateAsset(options *AssetUploadOptions, f io.Reader) (AssetUploadResponse, error) {
|
||||||
|
var assetInfo AssetUploadResponse
|
||||||
|
endpoint, err := url.Parse("https://data.roblox.com/Data/Upload.ashx?json=1&type=Model&genreTypeId=1")
|
||||||
|
if err != nil {
|
||||||
|
return assetInfo, err
|
||||||
|
}
|
||||||
|
|
||||||
|
query := endpoint.Query()
|
||||||
|
query.Set("name", options.Name)
|
||||||
|
query.Set("description", options.Description)
|
||||||
|
query.Set("assetid", strconv.Itoa(options.AssetID))
|
||||||
|
|
||||||
|
// Comments
|
||||||
|
if options.Comments {
|
||||||
|
query.Set("allowComments", "true")
|
||||||
|
} else {
|
||||||
|
query.Set("allowComments", "false")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public
|
||||||
|
if options.Public {
|
||||||
|
query.Set("ispublic", "true")
|
||||||
|
} else {
|
||||||
|
query.Set("ispublic", "false")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group
|
||||||
|
if options.Group > 0 {
|
||||||
|
query.Set("groupId", strconv.Itoa(options.Group))
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoint.RawQuery = query.Encode()
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", endpoint.String(), nil)
|
||||||
|
req.Header.Set("user-agent", "Roblox")
|
||||||
|
|
||||||
|
// Perform request
|
||||||
|
resp, err := s.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return assetInfo, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode == 403 && resp.Header.Get("X-Csrf-Token") != "" {
|
||||||
|
req, err := http.NewRequest("POST", endpoint.String(), f)
|
||||||
|
req.Header.Set("user-agent", "Roblox")
|
||||||
|
req.Header.Set("x-csrf-token", strings.Trim(resp.Header["X-Csrf-Token"][0], " "))
|
||||||
|
// Perform request
|
||||||
|
resp, err = s.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return assetInfo, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return assetInfo, fmt.Errorf(resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return assetInfo, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(body, &assetInfo); err != nil {
|
||||||
|
return assetInfo, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return assetInfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Session) Download(id int) (io.Reader, error) {
|
||||||
|
resp, err := s.client.Get("https://assetgame.roblox.com/Asset/?id=" + strconv.Itoa(id))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return nil, fmt.Errorf(resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.Body, nil
|
||||||
|
}
|
3
vendor/git.itzana.me/itzaname/go-roblox/go.mod
generated
vendored
Normal file
3
vendor/git.itzana.me/itzaname/go-roblox/go.mod
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module git.itzana.me/itzaname/go-roblox
|
||||||
|
|
||||||
|
go 1.15
|
156
vendor/git.itzana.me/itzaname/go-roblox/item.go
generated
vendored
Normal file
156
vendor/git.itzana.me/itzaname/go-roblox/item.go
generated
vendored
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
package roblox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Item struct containing data on retrieved items
|
||||||
|
type Item struct {
|
||||||
|
ProductID int
|
||||||
|
ItemID int
|
||||||
|
AssetID int
|
||||||
|
UserID int
|
||||||
|
UserName string
|
||||||
|
Type string
|
||||||
|
Name string
|
||||||
|
CopyLocked bool
|
||||||
|
Owned bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasItem will return if you own the item
|
||||||
|
func (s *Session) HasItem(id int) (bool, error) {
|
||||||
|
resp, err := s.client.Get(fmt.Sprintf("http://api.roblox.com/Ownership/HasAsset?userId=%d&assetId=%d", s.ID, id))
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
data, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(data) == "true", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddItem add item by id to inventory
|
||||||
|
func (s *Session) AddItem(id int) error {
|
||||||
|
product, err := s.GetProduct(id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
payload := struct {
|
||||||
|
ExpectedCurrency int `json:"expectedCurrency"`
|
||||||
|
ExpectedPrice int `json:"expectedPrice"`
|
||||||
|
ExpectedSellerID int `json:"expectedSellerId"`
|
||||||
|
}{
|
||||||
|
ExpectedCurrency: 1,
|
||||||
|
ExpectedPrice: 0,
|
||||||
|
ExpectedSellerID: product.Creator.ID,
|
||||||
|
}
|
||||||
|
// Gen json body
|
||||||
|
data, err := json.Marshal(&payload)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", fmt.Sprintf("https://economy.roblox.com/v1/purchases/products/%d", product.ProductID), bytes.NewBuffer(data))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := s.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode == 403 {
|
||||||
|
req, err := http.NewRequest("POST", fmt.Sprintf("https://economy.roblox.com/v1/purchases/products/%d", product.ProductID), bytes.NewBuffer(data))
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("X-Csrf-Token", resp.Header["X-Csrf-Token"][0])
|
||||||
|
|
||||||
|
resp, err := s.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return fmt.Errorf("Failed to add item. Status %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveItem will remove item from inventory
|
||||||
|
func (s *Session) RemoveItem(id int) error {
|
||||||
|
v := url.Values{}
|
||||||
|
v.Set("assetId", strconv.Itoa(id))
|
||||||
|
resp, err := s.client.Post("https://www.roblox.com/asset/delete-from-inventory", "application/x-www-form-urlencoded", bytes.NewBufferString(v.Encode()))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode == 403 {
|
||||||
|
req, err := http.NewRequest("POST", "https://www.roblox.com/asset/delete-from-inventory", bytes.NewBufferString(v.Encode()))
|
||||||
|
req.Header.Set("x-csrf-token", strings.Trim(resp.Header["X-Csrf-Token"][0], " "))
|
||||||
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
|
||||||
|
resp, err := s.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return fmt.Errorf("Failed to remove item. Status %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetModels will list models in inventory
|
||||||
|
func (s *Session) GetModels(user int) ([]Item, error) {
|
||||||
|
var Data []Item
|
||||||
|
|
||||||
|
resp, err := s.client.Get("https://www.roblox.com/users/inventory/list-json?assetTypeId=10&userId=" + strconv.Itoa(user))
|
||||||
|
if err != nil {
|
||||||
|
return Data, fmt.Errorf("Could not get list: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode == 200 {
|
||||||
|
var dat map[string]interface{}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
body, _ := ioutil.ReadAll(resp.Body)
|
||||||
|
|
||||||
|
if err := json.Unmarshal(body, &dat); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
set := dat["Data"].(map[string]interface{})
|
||||||
|
ilist := set["Items"].([]interface{})
|
||||||
|
for _, obj := range ilist {
|
||||||
|
itm := obj.(map[string]interface{})
|
||||||
|
iInfo := itm["Item"].(map[string]interface{})
|
||||||
|
iCreator := itm["Creator"].(map[string]interface{})
|
||||||
|
Data = append(Data, Item{0, int(iInfo["AssetId"].(float64)), 0, int(iCreator["Id"].(float64)), iCreator["Name"].(string), "Model", iInfo["Name"].(string), false, true})
|
||||||
|
}
|
||||||
|
|
||||||
|
return Data, nil
|
||||||
|
}
|
||||||
|
return Data, fmt.Errorf("Could not get models. Status: %d", resp.StatusCode)
|
||||||
|
}
|
61
vendor/git.itzana.me/itzaname/go-roblox/product.go
generated
vendored
Normal file
61
vendor/git.itzana.me/itzaname/go-roblox/product.go
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package roblox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Product contains info about a product
|
||||||
|
type Product struct {
|
||||||
|
TargetID int `json:"TargetId"`
|
||||||
|
ProductType string `json:"ProductType"`
|
||||||
|
AssetID int `json:"AssetId"`
|
||||||
|
ProductID int `json:"ProductId"`
|
||||||
|
Name string `json:"Name"`
|
||||||
|
Description string `json:"Description"`
|
||||||
|
AssetTypeID int `json:"AssetTypeId"`
|
||||||
|
Creator struct {
|
||||||
|
ID int `json:"Id"`
|
||||||
|
Name string `json:"Name"`
|
||||||
|
CreatorType string `json:"CreatorType"`
|
||||||
|
CreatorTargetID int `json:"CreatorTargetId"`
|
||||||
|
} `json:"Creator"`
|
||||||
|
IconImageAssetID int `json:"IconImageAssetId"`
|
||||||
|
Created time.Time `json:"Created"`
|
||||||
|
Updated time.Time `json:"Updated"`
|
||||||
|
PriceInRobux int `json:"PriceInRobux"`
|
||||||
|
PriceInTickets int `json:"PriceInTickets"`
|
||||||
|
Sales int `json:"Sales"`
|
||||||
|
IsNew bool `json:"IsNew"`
|
||||||
|
IsForSale bool `json:"IsForSale"`
|
||||||
|
IsPublicDomain bool `json:"IsPublicDomain"`
|
||||||
|
IsLimited bool `json:"IsLimited"`
|
||||||
|
IsLimitedUnique bool `json:"IsLimitedUnique"`
|
||||||
|
Remaining int `json:"Remaining"`
|
||||||
|
MinimumMembershipLevel int `json:"MinimumMembershipLevel"`
|
||||||
|
ContentRatingTypeID int `json:"ContentRatingTypeId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetProduct will retrieve store information on a product
|
||||||
|
func (s *Session) GetProduct(id int) (*Product, error) {
|
||||||
|
resp, err := s.client.Get(fmt.Sprintf("http://api.roblox.com/marketplace/productinfo?assetId=%d", id))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
data, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var info Product
|
||||||
|
err = json.Unmarshal(data, &info)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &info, nil
|
||||||
|
}
|
89
vendor/git.itzana.me/itzaname/go-roblox/session.go
generated
vendored
Normal file
89
vendor/git.itzana.me/itzaname/go-roblox/session.go
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
package roblox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/http/cookiejar"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Session struct for roblox login session data and members
|
||||||
|
type Session struct {
|
||||||
|
ID int
|
||||||
|
Username string
|
||||||
|
client *http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// New create a new session and logs in with provided data
|
||||||
|
func New(cookie string) (*Session, error) {
|
||||||
|
cookieJar, _ := cookiejar.New(nil)
|
||||||
|
rbxCookie := []*http.Cookie{&http.Cookie{
|
||||||
|
Name: ".ROBLOSECURITY",
|
||||||
|
Value: cookie,
|
||||||
|
}}
|
||||||
|
// url.Parse("http://www.roblox.com") // http://api.roblox.com
|
||||||
|
cookieJar.SetCookies(&url.URL{Scheme: "http", Host: "www.roblox.com"}, rbxCookie)
|
||||||
|
cookieJar.SetCookies(&url.URL{Scheme: "http", Host: "api.roblox.com"}, rbxCookie)
|
||||||
|
cookieJar.SetCookies(&url.URL{Scheme: "https", Host: "economy.roblox.com"}, rbxCookie)
|
||||||
|
cookieJar.SetCookies(&url.URL{Scheme: "https", Host: "data.roblox.com"}, rbxCookie)
|
||||||
|
client := &http.Client{
|
||||||
|
Jar: cookieJar,
|
||||||
|
}
|
||||||
|
|
||||||
|
session := Session{0, "", client}
|
||||||
|
|
||||||
|
/*err := session.Login(username, password)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Failed to login: %s", err)
|
||||||
|
}*/
|
||||||
|
|
||||||
|
info, err := session.GetUserInfo()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Failed to retrieve user information: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
session.ID = info.UserID
|
||||||
|
session.Username = info.UserName
|
||||||
|
|
||||||
|
return &session, err
|
||||||
|
}
|
||||||
|
|
||||||
|
/*func (s *Session) Login(username, password string) error {
|
||||||
|
details := struct {
|
||||||
|
Ctype string `json:"ctype"`
|
||||||
|
Cvalue string `json:"cvalue"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}{
|
||||||
|
"Username",
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
}
|
||||||
|
payload, err := json.Marshal(&details)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := s.client.Post("https://auth.roblox.com/v2/login", "application/json", bytes.NewBuffer(payload))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode == 403 {
|
||||||
|
req, err := http.NewRequest("POST", "https://auth.roblox.com/v2/login", bytes.NewBuffer(payload))
|
||||||
|
req.Header.Set("X-Csrf-Token", resp.Header["X-Csrf-Token"][0])
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := s.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return fmt.Errorf("Status %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}*/
|
37
vendor/git.itzana.me/itzaname/go-roblox/user.go
generated
vendored
Normal file
37
vendor/git.itzana.me/itzaname/go-roblox/user.go
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package roblox
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserInfo struct {
|
||||||
|
UserID int `json:"UserID"`
|
||||||
|
UserName string `json:"UserName"`
|
||||||
|
RobuxBalance int `json:"RobuxBalance"`
|
||||||
|
TicketsBalance int `json:"TicketsBalance"`
|
||||||
|
ThumbnailURL string `json:"ThumbnailUrl"`
|
||||||
|
IsAnyBuildersClubMember bool `json:"IsAnyBuildersClubMember"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserInfo will retrieve local user information
|
||||||
|
func (s *Session) GetUserInfo() (*UserInfo, error) {
|
||||||
|
resp, err := s.client.Get("http://www.roblox.com/mobileapi/userinfo")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
data, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var info UserInfo
|
||||||
|
err = json.Unmarshal(data, &info)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &info, nil
|
||||||
|
}
|
21
vendor/git.itzana.me/itzaname/rbxapi/LICENSE
generated
vendored
Normal file
21
vendor/git.itzana.me/itzaname/rbxapi/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Anaminus
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
14
vendor/git.itzana.me/itzaname/rbxapi/README.md
generated
vendored
Normal file
14
vendor/git.itzana.me/itzaname/rbxapi/README.md
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[![GoDoc](https://godoc.org/git.itzana.me/itzaname/rbxapi?status.png)](https://godoc.org/git.itzana.me/itzaname/rbxapi)
|
||||||
|
|
||||||
|
# rbxapi
|
||||||
|
|
||||||
|
The rbxapi package is a Go package used to represent information about the
|
||||||
|
Roblox Lua API.
|
||||||
|
|
||||||
|
## API References
|
||||||
|
|
||||||
|
- [rbxapi](https://godoc.org/git.itzana.me/itzaname/rbxapi)
|
||||||
|
- [patch](https://godoc.org/git.itzana.me/itzaname/rbxapi/patch): Used to represent information about differences between Roblox Lua API structures.
|
||||||
|
- [diff](https://godoc.org/git.itzana.me/itzaname/rbxapi/diff): Provides an implementation of the patch package for the generic rbxapi types.
|
||||||
|
- [rbxapidump](https://godoc.org/git.itzana.me/itzaname/rbxapi/rbxapidump): Implements the rbxapi interface as a codec for the Roblox API dump format.
|
||||||
|
- [rbxapijson](https://godoc.org/git.itzana.me/itzaname/rbxapi/rbxapijson): Implements the rbxapi package as a codec for the Roblox API dump in JSON format.
|
3
vendor/git.itzana.me/itzaname/rbxapi/go.mod
generated
vendored
Normal file
3
vendor/git.itzana.me/itzaname/rbxapi/go.mod
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module git.itzana.me/itzaname/rbxapi
|
||||||
|
|
||||||
|
go 1.16
|
219
vendor/git.itzana.me/itzaname/rbxapi/rbxapi.go
generated
vendored
Normal file
219
vendor/git.itzana.me/itzaname/rbxapi/rbxapi.go
generated
vendored
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
// The rbxapi package is used to represent information about the Roblox Lua
|
||||||
|
// API.
|
||||||
|
//
|
||||||
|
// This package provides a common interface for multiple implementations of
|
||||||
|
// the Roblox Lua API. The rbxapi interface may not be able to expose all
|
||||||
|
// information available from a particular implementation. If such information
|
||||||
|
// is required, it would be more suitable to use that implementation directly.
|
||||||
|
//
|
||||||
|
// The rbxapidump and rbxapijson subpackages provide implementations of the
|
||||||
|
// rbxapi interface.
|
||||||
|
package rbxapi
|
||||||
|
|
||||||
|
// Root represents the top-level structure of an API.
|
||||||
|
type Root interface {
|
||||||
|
// GetClasses returns a list of class descriptors present in the API.
|
||||||
|
// Items in the list must have a consistent order.
|
||||||
|
GetClasses() []Class
|
||||||
|
|
||||||
|
// GetClass returns the first class descriptor of the given name, or nil
|
||||||
|
// if no class of the given name is present.
|
||||||
|
GetClass(name string) Class
|
||||||
|
|
||||||
|
// GetEnums returns a list of enum descriptors present in the API. Items
|
||||||
|
// in the list must have a consistent order.
|
||||||
|
GetEnums() []Enum
|
||||||
|
|
||||||
|
// GetEnum returns the first enum descriptor of the given name, or nil if
|
||||||
|
// no enum of the given name is present.
|
||||||
|
GetEnum(name string) Enum
|
||||||
|
|
||||||
|
// Copy returns a deep copy of the API structure.
|
||||||
|
Copy() Root
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class represents a class descriptor.
|
||||||
|
type Class interface {
|
||||||
|
// GetName returns the class name.
|
||||||
|
GetName() string
|
||||||
|
|
||||||
|
// GetSuperclass returns the name of the class that this class inherits
|
||||||
|
// from.
|
||||||
|
GetSuperclass() string
|
||||||
|
|
||||||
|
// GetMembers returns a list of member descriptors belonging to the class.
|
||||||
|
// Items in the list must have a consistent order.
|
||||||
|
GetMembers() []Member
|
||||||
|
|
||||||
|
// GetMember returns the first member descriptor of the given name, or nil
|
||||||
|
// if no member of the given name is present.
|
||||||
|
GetMember(name string) Member
|
||||||
|
|
||||||
|
// Copy returns a deep copy of the class descriptor.
|
||||||
|
Copy() Class
|
||||||
|
|
||||||
|
Taggable
|
||||||
|
}
|
||||||
|
|
||||||
|
// Member represents a class member descriptor. A Member can be asserted to a
|
||||||
|
// more specific type. These are Property, Function, Event, and Callback.
|
||||||
|
type Member interface {
|
||||||
|
// GetMemberType returns a string indicating the the type of member.
|
||||||
|
GetMemberType() string
|
||||||
|
|
||||||
|
// GetName returns the name of the member.
|
||||||
|
GetName() string
|
||||||
|
|
||||||
|
// Copy returns a deep copy of the member descriptor.
|
||||||
|
Copy() Member
|
||||||
|
|
||||||
|
Taggable
|
||||||
|
}
|
||||||
|
|
||||||
|
// Property represents a class member of the Property member type.
|
||||||
|
type Property interface {
|
||||||
|
Member
|
||||||
|
|
||||||
|
// GetSecurity returns the security context associated with the property's
|
||||||
|
// read and write access.
|
||||||
|
GetSecurity() (read, write string)
|
||||||
|
|
||||||
|
// GetValueType returns the type of value stored in the property.
|
||||||
|
GetValueType() Type
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function represents a class member of the Function member type.
|
||||||
|
type Function interface {
|
||||||
|
Member
|
||||||
|
|
||||||
|
// GetSecurity returns the security context of the member's access.
|
||||||
|
GetSecurity() string
|
||||||
|
|
||||||
|
// GetParameters returns the list of parameters describing the arguments
|
||||||
|
// passed to the function. These parameters may have default values.
|
||||||
|
GetParameters() Parameters
|
||||||
|
|
||||||
|
// GetReturnType returns the type of value returned by the function.
|
||||||
|
GetReturnType() Type
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event represents a class member of the Event member type.
|
||||||
|
type Event interface {
|
||||||
|
Member
|
||||||
|
|
||||||
|
// GetSecurity returns the security context of the member's access.
|
||||||
|
GetSecurity() string
|
||||||
|
|
||||||
|
// GetParameters returns the list of parameters describing the arguments
|
||||||
|
// received from the event. These parameters cannot have default values.
|
||||||
|
GetParameters() Parameters
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback represents a class member of the Callback member type.
|
||||||
|
type Callback interface {
|
||||||
|
Member
|
||||||
|
|
||||||
|
// GetSecurity returns the security context of the member's access.
|
||||||
|
GetSecurity() string
|
||||||
|
|
||||||
|
// GetParameters returns the list of parameters describing the arguments
|
||||||
|
// passed to the callback. These parameters cannot have default values.
|
||||||
|
GetParameters() Parameters
|
||||||
|
|
||||||
|
// GetReturnType returns the type of value that is returned by the
|
||||||
|
// callback.
|
||||||
|
GetReturnType() Type
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameters represents a list of parameters of a function, event, or
|
||||||
|
// callback member.
|
||||||
|
type Parameters interface {
|
||||||
|
// GetLength returns the number of parameters in the list.
|
||||||
|
GetLength() int
|
||||||
|
|
||||||
|
// GetParameter returns the parameter indicated by the given index.
|
||||||
|
GetParameter(int) Parameter
|
||||||
|
|
||||||
|
// GetParameters returns a copy of the list as a slice.
|
||||||
|
GetParameters() []Parameter
|
||||||
|
|
||||||
|
// Copy returns a deep copy of the parameter list.
|
||||||
|
Copy() Parameters
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameter represents a single parameter of a function, event, or callback
|
||||||
|
// member.
|
||||||
|
type Parameter interface {
|
||||||
|
// GetType returns the type of the parameter value.
|
||||||
|
GetType() Type
|
||||||
|
|
||||||
|
// GetName returns the name describing the parameter.
|
||||||
|
GetName() string
|
||||||
|
|
||||||
|
// GetDefault returns a string representing the default value of the
|
||||||
|
// parameter, and whether a default value is present.
|
||||||
|
GetDefault() (value string, ok bool)
|
||||||
|
|
||||||
|
// Copy returns a deep copy of the parameter.
|
||||||
|
Copy() Parameter
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enum represents an enum descriptor.
|
||||||
|
type Enum interface {
|
||||||
|
// GetName returns the name of the enum.
|
||||||
|
GetName() string
|
||||||
|
|
||||||
|
// GetEnumItems returns a list of items of the enum. Items in the list
|
||||||
|
// must have a consistent order.
|
||||||
|
GetEnumItems() []EnumItem
|
||||||
|
|
||||||
|
// GetEnumItem returns the first item of the given name, or nil if no item
|
||||||
|
// of the given name is present.
|
||||||
|
GetEnumItem(name string) EnumItem
|
||||||
|
|
||||||
|
// Copy returns a deep copy of the enum descriptor.
|
||||||
|
Copy() Enum
|
||||||
|
|
||||||
|
Taggable
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnumItem represents an enum item descriptor.
|
||||||
|
type EnumItem interface {
|
||||||
|
// GetName returns the name of the enum item.
|
||||||
|
GetName() string
|
||||||
|
|
||||||
|
// GetValue returns the value of the enum item.
|
||||||
|
GetValue() int
|
||||||
|
|
||||||
|
// Copy returns a deep copy of the enum item descriptor.
|
||||||
|
Copy() EnumItem
|
||||||
|
|
||||||
|
Taggable
|
||||||
|
}
|
||||||
|
|
||||||
|
// Taggable indicates a descriptor that is capable of having tags.
|
||||||
|
type Taggable interface {
|
||||||
|
// GetTag returns whether the given tag is present in the descriptor.
|
||||||
|
GetTag(tag string) bool
|
||||||
|
|
||||||
|
// GetTags returns a list of all tags present in the descriptor. Items in
|
||||||
|
// the list must have a consistent order.
|
||||||
|
GetTags() []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type represents a value type.
|
||||||
|
type Type interface {
|
||||||
|
// GetName returns the name of the type.
|
||||||
|
GetName() string
|
||||||
|
|
||||||
|
// GetCategory returns the category of the type. This may be empty when a
|
||||||
|
// type category is inapplicable or unavailable.
|
||||||
|
GetCategory() string
|
||||||
|
|
||||||
|
// String returns a string representation of the entire type. The format
|
||||||
|
// of this string is implementation-dependent.
|
||||||
|
String() string
|
||||||
|
|
||||||
|
// Copy returns a deep copy of the type.
|
||||||
|
Copy() Type
|
||||||
|
}
|
21
vendor/git.itzana.me/itzaname/rbxfile/LICENSE
generated
vendored
Normal file
21
vendor/git.itzana.me/itzaname/rbxfile/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2014 Anaminus
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
49
vendor/git.itzana.me/itzaname/rbxfile/README.md
generated
vendored
Normal file
49
vendor/git.itzana.me/itzaname/rbxfile/README.md
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
[![GoDoc](https://godoc.org/git.itzana.me/itzaname/rbxfile?status.png)](https://godoc.org/git.itzana.me/itzaname/rbxfile)
|
||||||
|
|
||||||
|
# rbxfile
|
||||||
|
|
||||||
|
The rbxfile package handles the decoding, encoding, and manipulation of Roblox
|
||||||
|
instance data structures.
|
||||||
|
|
||||||
|
This package can be used to manipulate Roblox instance trees outside of the
|
||||||
|
Roblox client. Such data structures begin with a [Root][root] struct. A Root
|
||||||
|
contains a list of child [Instances][inst], which in turn contain more child
|
||||||
|
Instances, and so on, forming a tree of Instances. These Instances can be
|
||||||
|
accessed and manipulated using an API similar to that of Roblox.
|
||||||
|
|
||||||
|
Each Instance also has a set of "properties". Each property has a specific
|
||||||
|
value of a certain [type][type]. Every available type implements the
|
||||||
|
[Value][value] interface, and is prefixed with "Value".
|
||||||
|
|
||||||
|
Root structures can be decoded from and encoded to various formats, including
|
||||||
|
Roblox's native file formats. The two sub-packages [bin][bin] and [xml][xml]
|
||||||
|
provide formats for Roblox's binary and XML formats. Root structures can also
|
||||||
|
be encoded and decoded with the [json][json] package.
|
||||||
|
|
||||||
|
Besides decoding from a format, root structures can also be created manually.
|
||||||
|
The best way to do this is through the [declare][declare] sub-package, which
|
||||||
|
provides an easy way to generate root structures.
|
||||||
|
|
||||||
|
[root]: https://godoc.org/git.itzana.me/itzaname/rbxfile#Root
|
||||||
|
[inst]: https://godoc.org/git.itzana.me/itzaname/rbxfile#Instance
|
||||||
|
[type]: https://godoc.org/git.itzana.me/itzaname/rbxfile#Type
|
||||||
|
[value]: https://godoc.org/git.itzana.me/itzaname/rbxfile#Value
|
||||||
|
[bin]: https://godoc.org/git.itzana.me/itzaname/rbxfile/bin
|
||||||
|
[xml]: https://godoc.org/git.itzana.me/itzaname/rbxfile/xml
|
||||||
|
[json]: https://godoc.org/encoding/json
|
||||||
|
[declare]: https://godoc.org/git.itzana.me/itzaname/rbxfile/declare
|
||||||
|
|
||||||
|
## Related
|
||||||
|
The implementation of the binary file format is based largely on the
|
||||||
|
[RobloxFileSpec][spec] document, a reverse-engineered specification by Gregory
|
||||||
|
Comer.
|
||||||
|
|
||||||
|
Other projects that involve decoding and encoding Roblox files:
|
||||||
|
|
||||||
|
- [rbx-fmt](https://github.com/stravant/rbx-fmt): An implementation in C.
|
||||||
|
- [LibRbxl](https://github.com/GregoryComer/LibRbxl): An implementation in C#.
|
||||||
|
- [rbx-dom](https://github.com/LPGhatguy/rbx-dom): An implementation in Rust.
|
||||||
|
- [Roblox-File-Format](https://github.com/CloneTrooper1019/Roblox-File-Format):
|
||||||
|
An implementation in C#.
|
||||||
|
|
||||||
|
[spec]: https://www.classy-studios.com/Downloads/RobloxFileSpec.pdf
|
431
vendor/git.itzana.me/itzaname/rbxfile/file.go
generated
vendored
Normal file
431
vendor/git.itzana.me/itzaname/rbxfile/file.go
generated
vendored
Normal file
@ -0,0 +1,431 @@
|
|||||||
|
// The rbxfile package handles the decoding, encoding, and manipulation of
|
||||||
|
// Roblox instance data structures.
|
||||||
|
//
|
||||||
|
// This package can be used to manipulate Roblox instance trees outside of the
|
||||||
|
// Roblox client. Such data structures begin with a Root struct. A Root
|
||||||
|
// contains a list of child Instances, which in turn contain more child
|
||||||
|
// Instances, and so on, forming a tree of Instances. These Instances can be
|
||||||
|
// accessed and manipulated using an API similar to that of Roblox.
|
||||||
|
//
|
||||||
|
// Each Instance also has a set of "properties". Each property has a specific
|
||||||
|
// value of a certain type. Every available type implements the Value
|
||||||
|
// interface, and is prefixed with "Value".
|
||||||
|
//
|
||||||
|
// Root structures can be decoded from and encoded to various formats,
|
||||||
|
// including Roblox's native file formats. The two sub-packages "bin" and
|
||||||
|
// "xml" provide formats for Roblox's binary and XML formats. Root structures
|
||||||
|
// can also be encoded and decoded with the "json" package.
|
||||||
|
//
|
||||||
|
// Besides decoding from a format, root structures can also be created
|
||||||
|
// manually. The best way to do this is through the "declare" sub-package,
|
||||||
|
// which provides an easy way to generate root structures.
|
||||||
|
package rbxfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Root represents the root of an instance tree. Root is not itself an
|
||||||
|
// instance, but a container for multiple root instances.
|
||||||
|
type Root struct {
|
||||||
|
// Instances contains root instances contained in the tree.
|
||||||
|
Instances []*Instance
|
||||||
|
|
||||||
|
// Metadata contains metadata about the tree.
|
||||||
|
Metadata map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRoot returns a new initialized Root.
|
||||||
|
func NewRoot() *Root {
|
||||||
|
return &Root{
|
||||||
|
Instances: []*Instance{},
|
||||||
|
Metadata: map[string]string{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy creates a copy of the root and its contents.
|
||||||
|
//
|
||||||
|
// A copied reference within the tree is resolved so that it points to the
|
||||||
|
// corresponding copy of the original referent. Copied references that point
|
||||||
|
// to an instance which isn't being copied will still point to the same
|
||||||
|
// instance.
|
||||||
|
func (root *Root) Copy() *Root {
|
||||||
|
clone := &Root{
|
||||||
|
Instances: make([]*Instance, len(root.Instances)),
|
||||||
|
}
|
||||||
|
|
||||||
|
refs := make(References)
|
||||||
|
crefs := make(References)
|
||||||
|
propRefs := make([]PropRef, 0, 8)
|
||||||
|
for i, inst := range root.Instances {
|
||||||
|
clone.Instances[i] = inst.clone(refs, crefs, &propRefs)
|
||||||
|
}
|
||||||
|
for _, propRef := range propRefs {
|
||||||
|
if !crefs.Resolve(propRef) {
|
||||||
|
// Refers to an instance outside the tree, try getting the
|
||||||
|
// original referent.
|
||||||
|
refs.Resolve(propRef)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return clone
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instance represents a single Roblox instance.
|
||||||
|
type Instance struct {
|
||||||
|
// ClassName indicates the instance's type.
|
||||||
|
ClassName string
|
||||||
|
|
||||||
|
// Reference is a unique string used to refer to the instance from
|
||||||
|
// elsewhere in the tree.
|
||||||
|
Reference string
|
||||||
|
|
||||||
|
// IsService indicates whether the instance should be treated as a
|
||||||
|
// service.
|
||||||
|
IsService bool
|
||||||
|
|
||||||
|
// Properties is a map of properties of the instance. It maps the name of
|
||||||
|
// the property to its current value.
|
||||||
|
Properties map[string]Value
|
||||||
|
|
||||||
|
// Children contains instances that are the children of the current
|
||||||
|
// instance. If this field is set directly, then FixTree should be called
|
||||||
|
// afterwards to ensure the correctness of the tree.
|
||||||
|
Children []*Instance
|
||||||
|
|
||||||
|
// The parent of the instance. Can be nil.
|
||||||
|
parent *Instance
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInstance creates a new Instance of a given class, and an optional
|
||||||
|
// parent.
|
||||||
|
func NewInstance(className string, parent *Instance) *Instance {
|
||||||
|
inst := &Instance{
|
||||||
|
ClassName: className,
|
||||||
|
Reference: GenerateReference(),
|
||||||
|
Properties: make(map[string]Value, 0),
|
||||||
|
}
|
||||||
|
if parent != nil {
|
||||||
|
parent.Children = append(parent.Children, inst)
|
||||||
|
inst.parent = parent
|
||||||
|
}
|
||||||
|
return inst
|
||||||
|
}
|
||||||
|
|
||||||
|
// assertLoop returns an error if an instance being the child of a parent would
|
||||||
|
// create a circular reference.
|
||||||
|
func assertLoop(child, parent *Instance) error {
|
||||||
|
if parent == child {
|
||||||
|
return errors.New("attempt to set instance as its own parent")
|
||||||
|
}
|
||||||
|
if parent != nil && parent.IsDescendantOf(child) {
|
||||||
|
return errors.New("attempt to set parent would result in circular reference")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// addChild appends a child to the instance, and sets its parent. If the child
|
||||||
|
// is already the child of another instance, it is first removed.
|
||||||
|
func (inst *Instance) addChild(child *Instance) {
|
||||||
|
if child.parent != nil {
|
||||||
|
child.parent.RemoveChild(child)
|
||||||
|
}
|
||||||
|
inst.Children = append(inst.Children, child)
|
||||||
|
child.parent = inst
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddChild appends a child instance to the instance's list of children. If
|
||||||
|
// the child has a parent, it is first removed. The parent of the child is set
|
||||||
|
// to the instance. An error is returned if the instance is a descendant of
|
||||||
|
// the child, or if the child is the instance itself.
|
||||||
|
func (inst *Instance) AddChild(child *Instance) error {
|
||||||
|
if err := assertLoop(child, inst); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
inst.addChild(child)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddChildAt inserts a child instance into the instance's list of children at
|
||||||
|
// a given position. If the child has a parent, it is first removed. The
|
||||||
|
// parent of the child is set to the instance. If the index is outside the
|
||||||
|
// bounds of the list, then it is constrained. An error is returned if the
|
||||||
|
// instance is a descendant of the child, or if the child is the instance
|
||||||
|
// itself.
|
||||||
|
func (inst *Instance) AddChildAt(index int, child *Instance) error {
|
||||||
|
if err := assertLoop(child, inst); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if index < 0 {
|
||||||
|
index = 0
|
||||||
|
} else if index >= len(inst.Children) {
|
||||||
|
inst.addChild(child)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if child.parent != nil {
|
||||||
|
child.parent.RemoveChild(child)
|
||||||
|
}
|
||||||
|
inst.Children = append(inst.Children, nil)
|
||||||
|
copy(inst.Children[index+1:], inst.Children[index:])
|
||||||
|
inst.Children[index] = child
|
||||||
|
child.parent = inst
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// removeChildAt removes the child at the given index, which is assumed to be
|
||||||
|
// within bounds.
|
||||||
|
func (inst *Instance) removeChildAt(index int) (child *Instance) {
|
||||||
|
child = inst.Children[index]
|
||||||
|
child.parent = nil
|
||||||
|
copy(inst.Children[index:], inst.Children[index+1:])
|
||||||
|
inst.Children[len(inst.Children)-1] = nil
|
||||||
|
inst.Children = inst.Children[:len(inst.Children)-1]
|
||||||
|
return child
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveChild removes a child instance from the instance's list of children.
|
||||||
|
// The parent of the child is set to nil. Returns the removed child.
|
||||||
|
func (inst *Instance) RemoveChild(child *Instance) *Instance {
|
||||||
|
for index, c := range inst.Children {
|
||||||
|
if c == child {
|
||||||
|
return inst.removeChildAt(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveChildAt removes the child at a given position from the instance's
|
||||||
|
// list of children. The parent of the child is set to nil. If the index is
|
||||||
|
// outside the bounds of the list, then no children are removed. Returns the
|
||||||
|
// removed child.
|
||||||
|
func (inst *Instance) RemoveChildAt(index int) *Instance {
|
||||||
|
if index < 0 || index >= len(inst.Children) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return inst.removeChildAt(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveAll remove every child from the instance. The parent of each child is
|
||||||
|
// set to nil.
|
||||||
|
func (inst *Instance) RemoveAll() {
|
||||||
|
for i, child := range inst.Children {
|
||||||
|
child.parent = nil
|
||||||
|
inst.Children[i] = nil
|
||||||
|
}
|
||||||
|
inst.Children = inst.Children[:0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parent returns the parent of the instance. Can return nil if the instance
|
||||||
|
// has no parent.
|
||||||
|
func (inst *Instance) Parent() *Instance {
|
||||||
|
return inst.parent
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetParent sets the parent of the instance, removing itself from the
|
||||||
|
// children of the old parent, and adding itself as a child of the new parent.
|
||||||
|
// The parent can be set to nil. An error is returned if the parent is a
|
||||||
|
// descendant of the instance, or if the parent is the instance itself. If the
|
||||||
|
// new parent is the same as the old parent, then the position of the instance
|
||||||
|
// in the parent's children is unchanged.
|
||||||
|
func (inst *Instance) SetParent(parent *Instance) error {
|
||||||
|
if inst.parent == parent {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err := assertLoop(inst, parent); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if inst.parent != nil {
|
||||||
|
inst.parent.RemoveChild(inst)
|
||||||
|
}
|
||||||
|
if parent != nil {
|
||||||
|
parent.addChild(inst)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FixTree walks through the descendants of the instance tree top-down and
|
||||||
|
// ensures that the parental references are correct. Any descendants that cause
|
||||||
|
// a circular reference are removed and not traversed.
|
||||||
|
func (inst *Instance) FixTree() {
|
||||||
|
for i := 0; i < len(inst.Children); {
|
||||||
|
child := inst.Children[i]
|
||||||
|
if err := assertLoop(child, inst); err != nil {
|
||||||
|
inst.removeChildAt(i)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
child.parent = inst
|
||||||
|
child.FixTree()
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clone returns a deep copy of the instance while managing references.
|
||||||
|
func (inst *Instance) clone(refs, crefs References, propRefs *[]PropRef) *Instance {
|
||||||
|
clone := &Instance{
|
||||||
|
ClassName: inst.ClassName,
|
||||||
|
Reference: refs.Get(inst),
|
||||||
|
IsService: inst.IsService,
|
||||||
|
Children: make([]*Instance, len(inst.Children)),
|
||||||
|
Properties: make(map[string]Value, len(inst.Properties)),
|
||||||
|
}
|
||||||
|
crefs[clone.Reference] = clone
|
||||||
|
for name, value := range inst.Properties {
|
||||||
|
if value, ok := value.(ValueReference); ok {
|
||||||
|
*propRefs = append(*propRefs, PropRef{
|
||||||
|
Instance: clone,
|
||||||
|
Property: name,
|
||||||
|
Reference: refs.Get(value.Instance),
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
clone.Properties[name] = value.Copy()
|
||||||
|
}
|
||||||
|
for i, child := range inst.Children {
|
||||||
|
c := child.clone(refs, crefs, propRefs)
|
||||||
|
clone.Children[i] = c
|
||||||
|
c.parent = clone
|
||||||
|
}
|
||||||
|
return clone
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone returns a copy of the instance. Each property and all descendants are
|
||||||
|
// copied as well. Unlike Roblox's implementation, the Archivable property is
|
||||||
|
// ignored.
|
||||||
|
//
|
||||||
|
// A copied reference within the tree is resolved so that it points to the
|
||||||
|
// corresponding copy of the original referent. Copied references that point
|
||||||
|
// to an instance which isn't being copied will still point to the same
|
||||||
|
// instance.
|
||||||
|
func (inst *Instance) Clone() *Instance {
|
||||||
|
refs := make(References)
|
||||||
|
crefs := make(References)
|
||||||
|
propRefs := make([]PropRef, 0, 8)
|
||||||
|
clone := inst.clone(refs, crefs, &propRefs)
|
||||||
|
for _, propRef := range propRefs {
|
||||||
|
if !crefs.Resolve(propRef) {
|
||||||
|
// Refers to an instance outside the tree, try getting the
|
||||||
|
// original referent.
|
||||||
|
refs.Resolve(propRef)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return clone
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindFirstChild returns the first found child whose Name property matches
|
||||||
|
// the given name. Returns nil if no child was found. If recursive is true,
|
||||||
|
// then FindFirstChild will be called on descendants as well.
|
||||||
|
func (inst *Instance) FindFirstChild(name string, recursive bool) *Instance {
|
||||||
|
for _, child := range inst.Children {
|
||||||
|
if child.Name() == name {
|
||||||
|
return child
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if recursive {
|
||||||
|
for _, child := range inst.Children {
|
||||||
|
if desc := child.FindFirstChild(name, true); desc != nil {
|
||||||
|
return desc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFullName returns the "full" name of the instance, which is the combined
|
||||||
|
// names of the instance and every ancestor, separated by a `.` character.
|
||||||
|
func (inst *Instance) GetFullName() string {
|
||||||
|
// Note: Roblox's GetFullName stops at the first ancestor that is a
|
||||||
|
// ServiceProvider. Since recreating this behavior would require
|
||||||
|
// information about the class hierarchy, this implementation simply
|
||||||
|
// includes every ancestor.
|
||||||
|
|
||||||
|
names := make([]string, 0, 8)
|
||||||
|
|
||||||
|
object := inst
|
||||||
|
for object != nil {
|
||||||
|
names = append(names, object.Name())
|
||||||
|
object = object.Parent()
|
||||||
|
}
|
||||||
|
|
||||||
|
full := make([]byte, 0, 64)
|
||||||
|
for i := len(names) - 1; i > 0; i-- {
|
||||||
|
full = append(full, []byte(names[i])...)
|
||||||
|
full = append(full, '.')
|
||||||
|
}
|
||||||
|
full = append(full, []byte(names[0])...)
|
||||||
|
|
||||||
|
return string(full)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAncestorOf returns whether the instance is the ancestor of another
|
||||||
|
// instance.
|
||||||
|
func (inst *Instance) IsAncestorOf(descendant *Instance) bool {
|
||||||
|
if descendant != nil {
|
||||||
|
return descendant.IsDescendantOf(inst)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDescendantOf returns whether the instance is the descendant of another
|
||||||
|
// instance.
|
||||||
|
func (inst *Instance) IsDescendantOf(ancestor *Instance) bool {
|
||||||
|
parent := inst.Parent()
|
||||||
|
for parent != nil {
|
||||||
|
if parent == ancestor {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
parent = parent.Parent()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns the Name property of the instance, or an empty string if it is
|
||||||
|
// invalid or not defined.
|
||||||
|
func (inst *Instance) Name() string {
|
||||||
|
iname, ok := inst.Properties["Name"]
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
name, _ := iname.(ValueString)
|
||||||
|
return string(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements the fmt.Stringer interface by returning the Name of the
|
||||||
|
// instance, or the ClassName if Name isn't defined.
|
||||||
|
func (inst *Instance) String() string {
|
||||||
|
iname, ok := inst.Properties["Name"]
|
||||||
|
if !ok {
|
||||||
|
return inst.ClassName
|
||||||
|
}
|
||||||
|
|
||||||
|
name, _ := iname.(ValueString)
|
||||||
|
if string(name) == "" {
|
||||||
|
return inst.ClassName
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetName sets the Name property of the instance.
|
||||||
|
func (inst *Instance) SetName(name string) {
|
||||||
|
inst.Properties["Name"] = ValueString(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get returns the value of a property in the instance. The value will be nil
|
||||||
|
// if the property is not defined.
|
||||||
|
func (inst *Instance) Get(property string) (value Value) {
|
||||||
|
return inst.Properties[property]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets the value of a property in the instance. If value is nil, then the
|
||||||
|
// value will be deleted from the Properties map.
|
||||||
|
func (inst *Instance) Set(property string, value Value) {
|
||||||
|
if value == nil {
|
||||||
|
delete(inst.Properties, property)
|
||||||
|
} else {
|
||||||
|
inst.Properties[property] = value
|
||||||
|
}
|
||||||
|
}
|
9
vendor/git.itzana.me/itzaname/rbxfile/go.mod
generated
vendored
Normal file
9
vendor/git.itzana.me/itzaname/rbxfile/go.mod
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
module git.itzana.me/itzaname/rbxfile
|
||||||
|
|
||||||
|
go 1.15
|
||||||
|
|
||||||
|
require (
|
||||||
|
git.itzana.me/itzaname/rbxapi v0.1.0
|
||||||
|
github.com/anaminus/but v0.2.0
|
||||||
|
github.com/bkaradzic/go-lz4 v1.0.0
|
||||||
|
)
|
6
vendor/git.itzana.me/itzaname/rbxfile/go.sum
generated
vendored
Normal file
6
vendor/git.itzana.me/itzaname/rbxfile/go.sum
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
git.itzana.me/itzaname/rbxapi v0.1.0 h1:eBKdz34TJ+U6boV97E/NWncnS6LYtlV2sz34v/Sd1X4=
|
||||||
|
git.itzana.me/itzaname/rbxapi v0.1.0/go.mod h1:QrL2P6VPj7gin7/KhM+86HsZ4TqoPUJ9t5FjoduEYfY=
|
||||||
|
github.com/anaminus/but v0.2.0 h1:UPKY6UtvTZH8seod0rfVRsQxP8qssz+P6VE9a2AYeNY=
|
||||||
|
github.com/anaminus/but v0.2.0/go.mod h1:44z5qYo/3MWnZDi6ifH3IgrFWa1VFfdTttL3IYN/9R4=
|
||||||
|
github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAKk=
|
||||||
|
github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
|
102
vendor/git.itzana.me/itzaname/rbxfile/ref.go
generated
vendored
Normal file
102
vendor/git.itzana.me/itzaname/rbxfile/ref.go
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package rbxfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PropRef specifies the property of an instance that is a reference, which is
|
||||||
|
// to be resolved into its referent at a later time.
|
||||||
|
type PropRef struct {
|
||||||
|
Instance *Instance
|
||||||
|
Property string
|
||||||
|
Reference string
|
||||||
|
}
|
||||||
|
|
||||||
|
// References is a mapping of reference strings to Instances.
|
||||||
|
type References map[string]*Instance
|
||||||
|
|
||||||
|
// Resolve resolves a PropRef and sets the value of the property using
|
||||||
|
// References. If the referent does not exist, and the reference is not empty,
|
||||||
|
// then false is returned. True is returned otherwise.
|
||||||
|
func (refs References) Resolve(propRef PropRef) bool {
|
||||||
|
if refs == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if propRef.Instance == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
referent := refs[propRef.Reference]
|
||||||
|
propRef.Instance.Properties[propRef.Property] = ValueReference{
|
||||||
|
Instance: referent,
|
||||||
|
}
|
||||||
|
return referent != nil && !IsEmptyReference(propRef.Reference)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets a reference from an Instance, using References to check for
|
||||||
|
// duplicates. If the instance's reference already exists in References, then
|
||||||
|
// a new reference is generated and applied to the instance. The instance's
|
||||||
|
// reference is then added to References.
|
||||||
|
func (refs References) Get(instance *Instance) (ref string) {
|
||||||
|
if instance == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
ref = instance.Reference
|
||||||
|
if refs == nil {
|
||||||
|
return ref
|
||||||
|
}
|
||||||
|
// If the reference is not empty, or if the reference is not marked, or
|
||||||
|
// the marked reference already refers to the current instance, then do
|
||||||
|
// nothing.
|
||||||
|
if IsEmptyReference(ref) || refs[ref] != nil && refs[ref] != instance {
|
||||||
|
// Otherwise, regenerate the reference until it is not a duplicate.
|
||||||
|
for {
|
||||||
|
// If a generated reference matches a reference that was not yet
|
||||||
|
// traversed, then the latter reference will be regenerated, which
|
||||||
|
// may not match Roblox's implementation. It is difficult to
|
||||||
|
// discern whether this is correct because it is extremely
|
||||||
|
// unlikely that a duplicate will be generated.
|
||||||
|
ref = GenerateReference()
|
||||||
|
if _, ok := refs[ref]; !ok {
|
||||||
|
instance.Reference = ref
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Mark reference as taken.
|
||||||
|
refs[ref] = instance
|
||||||
|
return ref
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsEmptyReference returns whether a reference string is considered "empty",
|
||||||
|
// and therefore does not have a referent.
|
||||||
|
func IsEmptyReference(ref string) bool {
|
||||||
|
switch ref {
|
||||||
|
case "", "null", "nil":
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateUUID() string {
|
||||||
|
var buf [32]byte
|
||||||
|
if _, err := io.ReadFull(rand.Reader, buf[:16]); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
buf[6] = (buf[6] & 0x0F) | 0x40 // Version 4 ; 0100XXXX
|
||||||
|
buf[8] = (buf[8] & 0x3F) | 0x80 // Variant RFC4122 ; 10XXXXXX
|
||||||
|
const hextable = "0123456789ABCDEF"
|
||||||
|
for i := len(buf)/2 - 1; i >= 0; i-- {
|
||||||
|
buf[i*2+1] = hextable[buf[i]&0x0f]
|
||||||
|
buf[i*2] = hextable[buf[i]>>4]
|
||||||
|
}
|
||||||
|
return string(buf[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateReference generates a unique string that can be used as a reference
|
||||||
|
// to an Instance.
|
||||||
|
func GenerateReference() string {
|
||||||
|
return "RBX" + generateUUID()
|
||||||
|
}
|
89
vendor/git.itzana.me/itzaname/rbxfile/value_checklist.md
generated
vendored
Normal file
89
vendor/git.itzana.me/itzaname/rbxfile/value_checklist.md
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
To add value type `Foobar`:
|
||||||
|
|
||||||
|
- rbxfile
|
||||||
|
- `values.go`
|
||||||
|
- [ ] Add `TypeFoobar` to Type constants.
|
||||||
|
- [ ] In `typeStrings`, map `TypeFoobar` to string `"Foobar"`.
|
||||||
|
- [ ] In `valueGenerators`, map `TypeFoobar` to function
|
||||||
|
`newValueFoobar`.
|
||||||
|
- [ ] Create `ValueFoobar` type.
|
||||||
|
- [ ] Add `ValueFoobar` type with appropriate underlying type.
|
||||||
|
- [ ] Implement `newValueFoobar` function (`func() Value`)
|
||||||
|
- [ ] Implement `Type() Type` method.
|
||||||
|
- Return `TypeFoobar`.
|
||||||
|
- [ ] Implement `String() string` method.
|
||||||
|
- Return string representation of value that is similar to the
|
||||||
|
results of Roblox's `tostring` function.
|
||||||
|
- [ ] Implement `Copy() Value` method.
|
||||||
|
- Must return a deep copy of the underlying value.
|
||||||
|
- `values_test.go`
|
||||||
|
- ...
|
||||||
|
- declare
|
||||||
|
- `declare/type.go`
|
||||||
|
- [ ] Add `Foobar` to type constants.
|
||||||
|
- Ensure `Foobar` does not conflict with existing identifiers.
|
||||||
|
- [ ] In `typeStrings`, map `Foobar` to string `"Foobar"`.
|
||||||
|
- [ ] In function `assertValue`, add case `Foobar`.
|
||||||
|
- Assert `v` as `rbxfile.ValueFoobar`.
|
||||||
|
- [ ] In method `Type.value`, add case `Foobar`.
|
||||||
|
- Convert slice of arbitrary values to a `rbxfile.ValueFoobar`.
|
||||||
|
- `declare/declare.go`
|
||||||
|
- [ ] In function `Property`, document behavior of `Foobar` case in
|
||||||
|
`Type.value` method.
|
||||||
|
- `declare/declare_test.go`
|
||||||
|
- ...
|
||||||
|
- json
|
||||||
|
- `json/json.go`
|
||||||
|
- [ ] In function `ValueToJSONInterface`, add case
|
||||||
|
`rbxfile.ValueFoobar`.
|
||||||
|
- Convert `rbxfile.ValueFoobar` to generic JSON interface.
|
||||||
|
- [ ] In function `ValueFromJSONInterface`, add case
|
||||||
|
`rbxfile.TypeFoobar`.
|
||||||
|
- Convert generic JSON interface to `rbxfile.ValueFoobar`.
|
||||||
|
- xml
|
||||||
|
- `xml/codec.go`
|
||||||
|
- [ ] In function `GetCanonType` add case `"foobar"` (lowercase).
|
||||||
|
- Returns `"Foobar"`
|
||||||
|
- [ ] In method `rdecoder.getValue`, add case `"Foobar"`.
|
||||||
|
- Receives `tag *Tag`, must return `rbxfile.ValueFoobar`.
|
||||||
|
- `components` can be used to map subtags to value fields.
|
||||||
|
- [ ] In method `rencoder.encodeProperty`, add case
|
||||||
|
`rbxfile.ValueFoobar`.
|
||||||
|
- Returns `*Tag` that is decodable by `rdecoder.getValue`.
|
||||||
|
- [ ] In function `isCanonType`, add case `rbxfile.ValueFoobar`.
|
||||||
|
- bin
|
||||||
|
- `bin/values.go`
|
||||||
|
- [ ] Add `TypeFoobar` to type constants.
|
||||||
|
- [ ] In `typeStrings`, map `TypeFoobar` to `"Foobar"`.
|
||||||
|
- [ ] In `valueGenerators`, map `TypeFoobar` to function
|
||||||
|
`newValueFoobar`.
|
||||||
|
- [ ] Create `ValueFoobar` type.
|
||||||
|
- [ ] Add `ValueFoobar` with appropriate underlying type.
|
||||||
|
- [ ] Implement `newValueFoobar` function (`func() Value`).
|
||||||
|
- [ ] Implement `Type() Type` method.
|
||||||
|
- Returns `TypeFoobar`.
|
||||||
|
- [ ] Implement `ArrayBytes`.
|
||||||
|
- Converts a slice of `ValueFoobar` to a slice of bytes.
|
||||||
|
- If fields `ValueFoobar` must be interleaved, use
|
||||||
|
`interleaveFields`.
|
||||||
|
- [ ] Implement `FromArrayBytes`.
|
||||||
|
- Converts a slice of bytes to a slice of `ValueFoobar`.
|
||||||
|
- If fields of ValueFoobar` are interleaved, use
|
||||||
|
`deinterleaveFields`.
|
||||||
|
- [ ] Implement `Bytes`.
|
||||||
|
- Converts a single `ValueFoobar` to a slice of bytes.
|
||||||
|
- [ ] Implement `FromBytes`.
|
||||||
|
- Converts a slice of bytes to a single `ValueFoobar`.
|
||||||
|
- [ ] If fields of `ValueFoobar` must be interleaved, implement
|
||||||
|
`fielder` interface.
|
||||||
|
- [ ] Implement `fieldLen`.
|
||||||
|
- Returns the byte size of each field.
|
||||||
|
- [ ] Implement `fieldSet`.
|
||||||
|
- Sets field number `i` using bytes from `b`.
|
||||||
|
- [ ] Implement `fieldGet`.
|
||||||
|
- Returns field number `i` as a slice of bytes.
|
||||||
|
- `bin/codec.go`
|
||||||
|
- [ ] In function `decodeValue`, add case `*ValueFoobar`.
|
||||||
|
- Converts `*ValueFoobar` to `rbxfile.ValueFoobar`.
|
||||||
|
- [ ] In function `encodeValue`, add case `rbxfile.ValueFoobar`.
|
||||||
|
- Converts `rbxfile.ValueFoobar` to `*ValueFoobar`.
|
950
vendor/git.itzana.me/itzaname/rbxfile/values.go
generated
vendored
Normal file
950
vendor/git.itzana.me/itzaname/rbxfile/values.go
generated
vendored
Normal file
@ -0,0 +1,950 @@
|
|||||||
|
package rbxfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.itzana.me/itzaname/rbxapi"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Type represents a Roblox type.
|
||||||
|
type Type byte
|
||||||
|
|
||||||
|
// String returns a string representation of the type. If the type is not
|
||||||
|
// valid, then the returned value will be "Invalid".
|
||||||
|
func (t Type) String() string {
|
||||||
|
s, ok := typeStrings[t]
|
||||||
|
if !ok {
|
||||||
|
return "Invalid"
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
TypeInvalid Type = iota
|
||||||
|
TypeString
|
||||||
|
TypeBinaryString
|
||||||
|
TypeProtectedString
|
||||||
|
TypeContent
|
||||||
|
TypeBool
|
||||||
|
TypeInt
|
||||||
|
TypeFloat
|
||||||
|
TypeDouble
|
||||||
|
TypeUDim
|
||||||
|
TypeUDim2
|
||||||
|
TypeRay
|
||||||
|
TypeFaces
|
||||||
|
TypeAxes
|
||||||
|
TypeBrickColor
|
||||||
|
TypeColor3
|
||||||
|
TypeVector2
|
||||||
|
TypeVector3
|
||||||
|
TypeCFrame
|
||||||
|
TypeToken
|
||||||
|
TypeReference
|
||||||
|
TypeVector3int16
|
||||||
|
TypeVector2int16
|
||||||
|
TypeNumberSequence
|
||||||
|
TypeColorSequence
|
||||||
|
TypeNumberRange
|
||||||
|
TypeRect2D
|
||||||
|
TypePhysicalProperties
|
||||||
|
TypeColor3uint8
|
||||||
|
TypeInt64
|
||||||
|
TypeSharedString
|
||||||
|
)
|
||||||
|
|
||||||
|
// TypeFromString returns a Type from its string representation. TypeInvalid
|
||||||
|
// is returned if the string does not represent an existing Type.
|
||||||
|
func TypeFromString(s string) Type {
|
||||||
|
for typ, str := range typeStrings {
|
||||||
|
if s == str {
|
||||||
|
return typ
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TypeInvalid
|
||||||
|
}
|
||||||
|
|
||||||
|
// TypeFromAPIString returns a Type from a string, using a rbxapi.Root if
|
||||||
|
// needed. Valid strings are compatible with type strings typically found in a
|
||||||
|
// rbxapi.Root.
|
||||||
|
func TypeFromAPIString(api rbxapi.Root, s string) Type {
|
||||||
|
if api != nil && api.GetEnum(s) != nil {
|
||||||
|
return TypeToken
|
||||||
|
}
|
||||||
|
s = strings.ToLower(s)
|
||||||
|
switch s {
|
||||||
|
case "coordinateframe":
|
||||||
|
return TypeCFrame
|
||||||
|
case "object":
|
||||||
|
return TypeReference
|
||||||
|
}
|
||||||
|
for typ, str := range typeStrings {
|
||||||
|
if s == strings.ToLower(str) {
|
||||||
|
return typ
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TypeInvalid
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var typeStrings = map[Type]string{
|
||||||
|
TypeString: "String",
|
||||||
|
TypeBinaryString: "BinaryString",
|
||||||
|
TypeProtectedString: "ProtectedString",
|
||||||
|
TypeContent: "Content",
|
||||||
|
TypeBool: "Bool",
|
||||||
|
TypeInt: "Int",
|
||||||
|
TypeFloat: "Float",
|
||||||
|
TypeDouble: "Double",
|
||||||
|
TypeUDim: "UDim",
|
||||||
|
TypeUDim2: "UDim2",
|
||||||
|
TypeRay: "Ray",
|
||||||
|
TypeFaces: "Faces",
|
||||||
|
TypeAxes: "Axes",
|
||||||
|
TypeBrickColor: "BrickColor",
|
||||||
|
TypeColor3: "Color3",
|
||||||
|
TypeVector2: "Vector2",
|
||||||
|
TypeVector3: "Vector3",
|
||||||
|
TypeCFrame: "CFrame",
|
||||||
|
TypeToken: "Token",
|
||||||
|
TypeReference: "Reference",
|
||||||
|
TypeVector3int16: "Vector3int16",
|
||||||
|
TypeVector2int16: "Vector2int16",
|
||||||
|
TypeNumberSequence: "NumberSequence",
|
||||||
|
TypeColorSequence: "ColorSequence",
|
||||||
|
TypeNumberRange: "NumberRange",
|
||||||
|
TypeRect2D: "Rect2D",
|
||||||
|
TypePhysicalProperties: "PhysicalProperties",
|
||||||
|
TypeColor3uint8: "Color3uint8",
|
||||||
|
TypeInt64: "Int64",
|
||||||
|
TypeSharedString: "SharedString",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value holds a value of a particular Type.
|
||||||
|
type Value interface {
|
||||||
|
// Type returns an identifier indicating the type.
|
||||||
|
Type() Type
|
||||||
|
|
||||||
|
// String returns a string representation of the current value.
|
||||||
|
String() string
|
||||||
|
|
||||||
|
// Copy returns a copy of the value, which can be safely modified.
|
||||||
|
Copy() Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewValue returns new Value of the given Type. The initial value will not
|
||||||
|
// necessarily be the zero for the type. If the given type is invalid, then a
|
||||||
|
// nil value is returned.
|
||||||
|
func NewValue(typ Type) Value {
|
||||||
|
newValue, ok := valueGenerators[typ]
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return newValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
type valueGenerator func() Value
|
||||||
|
|
||||||
|
var valueGenerators = map[Type]valueGenerator{
|
||||||
|
TypeString: newValueString,
|
||||||
|
TypeBinaryString: newValueBinaryString,
|
||||||
|
TypeProtectedString: newValueProtectedString,
|
||||||
|
TypeContent: newValueContent,
|
||||||
|
TypeBool: newValueBool,
|
||||||
|
TypeInt: newValueInt,
|
||||||
|
TypeFloat: newValueFloat,
|
||||||
|
TypeDouble: newValueDouble,
|
||||||
|
TypeUDim: newValueUDim,
|
||||||
|
TypeUDim2: newValueUDim2,
|
||||||
|
TypeRay: newValueRay,
|
||||||
|
TypeFaces: newValueFaces,
|
||||||
|
TypeAxes: newValueAxes,
|
||||||
|
TypeBrickColor: newValueBrickColor,
|
||||||
|
TypeColor3: newValueColor3,
|
||||||
|
TypeVector2: newValueVector2,
|
||||||
|
TypeVector3: newValueVector3,
|
||||||
|
TypeCFrame: newValueCFrame,
|
||||||
|
TypeToken: newValueToken,
|
||||||
|
TypeReference: newValueReference,
|
||||||
|
TypeVector3int16: newValueVector3int16,
|
||||||
|
TypeVector2int16: newValueVector2int16,
|
||||||
|
TypeNumberSequence: newValueNumberSequence,
|
||||||
|
TypeColorSequence: newValueColorSequence,
|
||||||
|
TypeNumberRange: newValueNumberRange,
|
||||||
|
TypeRect2D: newValueRect2D,
|
||||||
|
TypePhysicalProperties: newValuePhysicalProperties,
|
||||||
|
TypeColor3uint8: newValueColor3uint8,
|
||||||
|
TypeInt64: newValueInt64,
|
||||||
|
TypeSharedString: newValueSharedString,
|
||||||
|
}
|
||||||
|
|
||||||
|
func joinstr(a ...string) string {
|
||||||
|
n := 0
|
||||||
|
for i := 0; i < len(a); i++ {
|
||||||
|
n += len(a[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
b := make([]byte, n)
|
||||||
|
bp := 0
|
||||||
|
for _, s := range a {
|
||||||
|
bp += copy(b[bp:], s)
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
// Values
|
||||||
|
|
||||||
|
type ValueString []byte
|
||||||
|
|
||||||
|
func newValueString() Value {
|
||||||
|
return make(ValueString, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueString) Type() Type {
|
||||||
|
return TypeString
|
||||||
|
}
|
||||||
|
func (t ValueString) String() string {
|
||||||
|
return string(t)
|
||||||
|
}
|
||||||
|
func (t ValueString) Copy() Value {
|
||||||
|
c := make(ValueString, len(t))
|
||||||
|
copy(c, t)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueBinaryString []byte
|
||||||
|
|
||||||
|
func newValueBinaryString() Value {
|
||||||
|
return make(ValueBinaryString, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueBinaryString) Type() Type {
|
||||||
|
return TypeBinaryString
|
||||||
|
}
|
||||||
|
func (t ValueBinaryString) String() string {
|
||||||
|
return string(t)
|
||||||
|
}
|
||||||
|
func (t ValueBinaryString) Copy() Value {
|
||||||
|
c := make(ValueBinaryString, len(t))
|
||||||
|
copy(c, t)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueProtectedString []byte
|
||||||
|
|
||||||
|
func newValueProtectedString() Value {
|
||||||
|
return make(ValueProtectedString, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueProtectedString) Type() Type {
|
||||||
|
return TypeProtectedString
|
||||||
|
}
|
||||||
|
func (t ValueProtectedString) String() string {
|
||||||
|
return string(t)
|
||||||
|
}
|
||||||
|
func (t ValueProtectedString) Copy() Value {
|
||||||
|
c := make(ValueProtectedString, len(t))
|
||||||
|
copy(c, t)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueContent []byte
|
||||||
|
|
||||||
|
func newValueContent() Value {
|
||||||
|
return make(ValueContent, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueContent) Type() Type {
|
||||||
|
return TypeContent
|
||||||
|
}
|
||||||
|
func (t ValueContent) String() string {
|
||||||
|
return string(t)
|
||||||
|
}
|
||||||
|
func (t ValueContent) Copy() Value {
|
||||||
|
c := make(ValueContent, len(t))
|
||||||
|
copy(c, t)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueBool bool
|
||||||
|
|
||||||
|
func newValueBool() Value {
|
||||||
|
return *new(ValueBool)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueBool) Type() Type {
|
||||||
|
return TypeBool
|
||||||
|
}
|
||||||
|
func (t ValueBool) String() string {
|
||||||
|
if t {
|
||||||
|
return "true"
|
||||||
|
} else {
|
||||||
|
return "false"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (t ValueBool) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueInt int32
|
||||||
|
|
||||||
|
func newValueInt() Value {
|
||||||
|
return *new(ValueInt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueInt) Type() Type {
|
||||||
|
return TypeInt
|
||||||
|
}
|
||||||
|
func (t ValueInt) String() string {
|
||||||
|
return strconv.FormatInt(int64(t), 10)
|
||||||
|
}
|
||||||
|
func (t ValueInt) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueFloat float32
|
||||||
|
|
||||||
|
func newValueFloat() Value {
|
||||||
|
return *new(ValueFloat)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueFloat) Type() Type {
|
||||||
|
return TypeFloat
|
||||||
|
}
|
||||||
|
func (t ValueFloat) String() string {
|
||||||
|
return strconv.FormatFloat(float64(t), 'f', -1, 32)
|
||||||
|
}
|
||||||
|
func (t ValueFloat) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueDouble float64
|
||||||
|
|
||||||
|
func newValueDouble() Value {
|
||||||
|
return *new(ValueDouble)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueDouble) Type() Type {
|
||||||
|
return TypeDouble
|
||||||
|
}
|
||||||
|
func (t ValueDouble) String() string {
|
||||||
|
return strconv.FormatFloat(float64(t), 'f', -1, 64)
|
||||||
|
}
|
||||||
|
func (t ValueDouble) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueUDim struct {
|
||||||
|
Scale float32
|
||||||
|
Offset int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func newValueUDim() Value {
|
||||||
|
return *new(ValueUDim)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueUDim) Type() Type {
|
||||||
|
return TypeUDim
|
||||||
|
}
|
||||||
|
func (t ValueUDim) String() string {
|
||||||
|
return joinstr(
|
||||||
|
strconv.FormatFloat(float64(t.Scale), 'f', -1, 32),
|
||||||
|
", ",
|
||||||
|
strconv.FormatInt(int64(t.Offset), 10),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func (t ValueUDim) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueUDim2 struct {
|
||||||
|
X, Y ValueUDim
|
||||||
|
}
|
||||||
|
|
||||||
|
func newValueUDim2() Value {
|
||||||
|
return *new(ValueUDim2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueUDim2) Type() Type {
|
||||||
|
return TypeUDim2
|
||||||
|
}
|
||||||
|
func (t ValueUDim2) String() string {
|
||||||
|
return joinstr(
|
||||||
|
"{",
|
||||||
|
t.X.String(),
|
||||||
|
"}, {",
|
||||||
|
t.Y.String(),
|
||||||
|
"}",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func (t ValueUDim2) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueRay struct {
|
||||||
|
Origin, Direction ValueVector3
|
||||||
|
}
|
||||||
|
|
||||||
|
func newValueRay() Value {
|
||||||
|
return *new(ValueRay)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueRay) Type() Type {
|
||||||
|
return TypeRay
|
||||||
|
}
|
||||||
|
func (t ValueRay) String() string {
|
||||||
|
return joinstr(
|
||||||
|
"{",
|
||||||
|
t.Origin.String(),
|
||||||
|
"}, {",
|
||||||
|
t.Direction.String(),
|
||||||
|
"}",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func (t ValueRay) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueFaces struct {
|
||||||
|
Right, Top, Back, Left, Bottom, Front bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func newValueFaces() Value {
|
||||||
|
return *new(ValueFaces)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueFaces) Type() Type {
|
||||||
|
return TypeFaces
|
||||||
|
}
|
||||||
|
func (t ValueFaces) String() string {
|
||||||
|
s := make([]string, 0, 6)
|
||||||
|
if t.Front {
|
||||||
|
s = append(s, "Front")
|
||||||
|
}
|
||||||
|
if t.Bottom {
|
||||||
|
s = append(s, "Bottom")
|
||||||
|
}
|
||||||
|
if t.Left {
|
||||||
|
s = append(s, "Left")
|
||||||
|
}
|
||||||
|
if t.Back {
|
||||||
|
s = append(s, "Back")
|
||||||
|
}
|
||||||
|
if t.Top {
|
||||||
|
s = append(s, "Top")
|
||||||
|
}
|
||||||
|
if t.Right {
|
||||||
|
s = append(s, "Right")
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(s, ", ")
|
||||||
|
}
|
||||||
|
func (t ValueFaces) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueAxes struct {
|
||||||
|
X, Y, Z bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func newValueAxes() Value {
|
||||||
|
return *new(ValueAxes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueAxes) Type() Type {
|
||||||
|
return TypeAxes
|
||||||
|
}
|
||||||
|
func (t ValueAxes) String() string {
|
||||||
|
s := make([]string, 0, 3)
|
||||||
|
if t.X {
|
||||||
|
s = append(s, "X")
|
||||||
|
}
|
||||||
|
if t.Y {
|
||||||
|
s = append(s, "Y")
|
||||||
|
}
|
||||||
|
if t.Z {
|
||||||
|
s = append(s, "Z")
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(s, ", ")
|
||||||
|
}
|
||||||
|
func (t ValueAxes) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueBrickColor uint32
|
||||||
|
|
||||||
|
func newValueBrickColor() Value {
|
||||||
|
return *new(ValueBrickColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueBrickColor) Type() Type {
|
||||||
|
return TypeBrickColor
|
||||||
|
}
|
||||||
|
func (t ValueBrickColor) String() string {
|
||||||
|
return strconv.FormatUint(uint64(t), 10)
|
||||||
|
}
|
||||||
|
func (t ValueBrickColor) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueColor3 struct {
|
||||||
|
R, G, B float32
|
||||||
|
}
|
||||||
|
|
||||||
|
func newValueColor3() Value {
|
||||||
|
return *new(ValueColor3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueColor3) Type() Type {
|
||||||
|
return TypeColor3
|
||||||
|
}
|
||||||
|
func (t ValueColor3) String() string {
|
||||||
|
return joinstr(
|
||||||
|
strconv.FormatFloat(float64(t.R), 'f', -1, 32),
|
||||||
|
", ",
|
||||||
|
strconv.FormatFloat(float64(t.G), 'f', -1, 32),
|
||||||
|
", ",
|
||||||
|
strconv.FormatFloat(float64(t.B), 'f', -1, 32),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func (t ValueColor3) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueVector2 struct {
|
||||||
|
X, Y float32
|
||||||
|
}
|
||||||
|
|
||||||
|
func newValueVector2() Value {
|
||||||
|
return *new(ValueVector2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueVector2) Type() Type {
|
||||||
|
return TypeVector2
|
||||||
|
}
|
||||||
|
func (t ValueVector2) String() string {
|
||||||
|
return joinstr(
|
||||||
|
strconv.FormatFloat(float64(t.X), 'f', -1, 32),
|
||||||
|
", ",
|
||||||
|
strconv.FormatFloat(float64(t.Y), 'f', -1, 32),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func (t ValueVector2) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueVector3 struct {
|
||||||
|
X, Y, Z float32
|
||||||
|
}
|
||||||
|
|
||||||
|
func newValueVector3() Value {
|
||||||
|
return *new(ValueVector3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueVector3) Type() Type {
|
||||||
|
return TypeVector3
|
||||||
|
}
|
||||||
|
func (t ValueVector3) String() string {
|
||||||
|
return joinstr(
|
||||||
|
strconv.FormatFloat(float64(t.X), 'f', -1, 32),
|
||||||
|
", ",
|
||||||
|
strconv.FormatFloat(float64(t.Y), 'f', -1, 32),
|
||||||
|
", ",
|
||||||
|
strconv.FormatFloat(float64(t.Z), 'f', -1, 32),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func (t ValueVector3) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueCFrame struct {
|
||||||
|
Position ValueVector3
|
||||||
|
Rotation [9]float32
|
||||||
|
}
|
||||||
|
|
||||||
|
func newValueCFrame() Value {
|
||||||
|
return ValueCFrame{
|
||||||
|
Position: ValueVector3{0, 0, 0},
|
||||||
|
Rotation: [9]float32{1, 0, 0, 0, 1, 0, 0, 0, 1},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueCFrame) Type() Type {
|
||||||
|
return TypeCFrame
|
||||||
|
}
|
||||||
|
func (t ValueCFrame) String() string {
|
||||||
|
s := make([]string, 12)
|
||||||
|
s[0] = strconv.FormatFloat(float64(t.Position.X), 'f', -1, 32)
|
||||||
|
s[1] = strconv.FormatFloat(float64(t.Position.Y), 'f', -1, 32)
|
||||||
|
s[2] = strconv.FormatFloat(float64(t.Position.Z), 'f', -1, 32)
|
||||||
|
for i, f := range t.Rotation {
|
||||||
|
s[i+3] = strconv.FormatFloat(float64(f), 'f', -1, 32)
|
||||||
|
}
|
||||||
|
return strings.Join(s, ", ")
|
||||||
|
}
|
||||||
|
func (t ValueCFrame) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueToken uint32
|
||||||
|
|
||||||
|
func newValueToken() Value {
|
||||||
|
return *new(ValueToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueToken) Type() Type {
|
||||||
|
return TypeToken
|
||||||
|
}
|
||||||
|
func (t ValueToken) String() string {
|
||||||
|
return strconv.FormatInt(int64(t), 10)
|
||||||
|
}
|
||||||
|
func (t ValueToken) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueReference struct {
|
||||||
|
*Instance
|
||||||
|
}
|
||||||
|
|
||||||
|
func newValueReference() Value {
|
||||||
|
return *new(ValueReference)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueReference) Type() Type {
|
||||||
|
return TypeReference
|
||||||
|
}
|
||||||
|
func (t ValueReference) String() string {
|
||||||
|
if t.Instance == nil {
|
||||||
|
return "<nil>"
|
||||||
|
}
|
||||||
|
return t.Name()
|
||||||
|
}
|
||||||
|
func (t ValueReference) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueVector3int16 struct {
|
||||||
|
X, Y, Z int16
|
||||||
|
}
|
||||||
|
|
||||||
|
func newValueVector3int16() Value {
|
||||||
|
return *new(ValueVector3int16)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueVector3int16) Type() Type {
|
||||||
|
return TypeVector3int16
|
||||||
|
}
|
||||||
|
func (t ValueVector3int16) String() string {
|
||||||
|
return joinstr(
|
||||||
|
strconv.FormatInt(int64(t.X), 10),
|
||||||
|
", ",
|
||||||
|
strconv.FormatInt(int64(t.Y), 10),
|
||||||
|
", ",
|
||||||
|
strconv.FormatInt(int64(t.Z), 10),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func (t ValueVector3int16) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueVector2int16 struct {
|
||||||
|
X, Y int16
|
||||||
|
}
|
||||||
|
|
||||||
|
func newValueVector2int16() Value {
|
||||||
|
return *new(ValueVector2int16)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueVector2int16) Type() Type {
|
||||||
|
return TypeVector2int16
|
||||||
|
}
|
||||||
|
func (t ValueVector2int16) String() string {
|
||||||
|
return joinstr(
|
||||||
|
strconv.FormatInt(int64(t.X), 10),
|
||||||
|
", ",
|
||||||
|
strconv.FormatInt(int64(t.Y), 10),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func (t ValueVector2int16) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueNumberSequenceKeypoint struct {
|
||||||
|
Time, Value, Envelope float32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t ValueNumberSequenceKeypoint) String() string {
|
||||||
|
return joinstr(
|
||||||
|
strconv.FormatFloat(float64(t.Time), 'f', -1, 32),
|
||||||
|
" ",
|
||||||
|
strconv.FormatFloat(float64(t.Value), 'f', -1, 32),
|
||||||
|
" ",
|
||||||
|
strconv.FormatFloat(float64(t.Envelope), 'f', -1, 32),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ValueNumberSequence []ValueNumberSequenceKeypoint
|
||||||
|
|
||||||
|
func newValueNumberSequence() Value {
|
||||||
|
return make(ValueNumberSequence, 0, 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueNumberSequence) Type() Type {
|
||||||
|
return TypeNumberSequence
|
||||||
|
}
|
||||||
|
func (t ValueNumberSequence) String() string {
|
||||||
|
b := make([]byte, 0, 64)
|
||||||
|
for _, v := range t {
|
||||||
|
b = append(b, []byte(v.String())...)
|
||||||
|
b = append(b, ' ')
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
func (t ValueNumberSequence) Copy() Value {
|
||||||
|
c := make(ValueNumberSequence, len(t))
|
||||||
|
copy(c, t)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueColorSequenceKeypoint struct {
|
||||||
|
Time float32
|
||||||
|
Value ValueColor3
|
||||||
|
Envelope float32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t ValueColorSequenceKeypoint) String() string {
|
||||||
|
return joinstr(
|
||||||
|
strconv.FormatFloat(float64(t.Time), 'f', -1, 32),
|
||||||
|
" ",
|
||||||
|
strconv.FormatFloat(float64(t.Value.R), 'f', -1, 32),
|
||||||
|
" ",
|
||||||
|
strconv.FormatFloat(float64(t.Value.G), 'f', -1, 32),
|
||||||
|
" ",
|
||||||
|
strconv.FormatFloat(float64(t.Value.B), 'f', -1, 32),
|
||||||
|
" ",
|
||||||
|
strconv.FormatFloat(float64(t.Envelope), 'f', -1, 32),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ValueColorSequence []ValueColorSequenceKeypoint
|
||||||
|
|
||||||
|
func newValueColorSequence() Value {
|
||||||
|
return make(ValueColorSequence, 0, 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueColorSequence) Type() Type {
|
||||||
|
return TypeColorSequence
|
||||||
|
}
|
||||||
|
func (t ValueColorSequence) String() string {
|
||||||
|
b := make([]byte, 0, 64)
|
||||||
|
for _, v := range t {
|
||||||
|
b = append(b, []byte(v.String())...)
|
||||||
|
b = append(b, ' ')
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
func (t ValueColorSequence) Copy() Value {
|
||||||
|
c := make(ValueColorSequence, len(t))
|
||||||
|
copy(c, t)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueNumberRange struct {
|
||||||
|
Min, Max float32
|
||||||
|
}
|
||||||
|
|
||||||
|
func newValueNumberRange() Value {
|
||||||
|
return *new(ValueNumberRange)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueNumberRange) Type() Type {
|
||||||
|
return TypeNumberRange
|
||||||
|
}
|
||||||
|
func (t ValueNumberRange) String() string {
|
||||||
|
return joinstr(
|
||||||
|
strconv.FormatFloat(float64(t.Min), 'f', -1, 32),
|
||||||
|
" ",
|
||||||
|
strconv.FormatFloat(float64(t.Max), 'f', -1, 32),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func (t ValueNumberRange) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueRect2D struct {
|
||||||
|
Min, Max ValueVector2
|
||||||
|
}
|
||||||
|
|
||||||
|
func newValueRect2D() Value {
|
||||||
|
return *new(ValueRect2D)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueRect2D) Type() Type {
|
||||||
|
return TypeRect2D
|
||||||
|
}
|
||||||
|
func (t ValueRect2D) String() string {
|
||||||
|
return joinstr(
|
||||||
|
strconv.FormatFloat(float64(t.Min.X), 'f', -1, 32),
|
||||||
|
", ",
|
||||||
|
strconv.FormatFloat(float64(t.Min.Y), 'f', -1, 32),
|
||||||
|
", ",
|
||||||
|
strconv.FormatFloat(float64(t.Max.X), 'f', -1, 32),
|
||||||
|
", ",
|
||||||
|
strconv.FormatFloat(float64(t.Max.Y), 'f', -1, 32),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func (t ValueRect2D) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValuePhysicalProperties struct {
|
||||||
|
CustomPhysics bool
|
||||||
|
Density float32
|
||||||
|
Friction float32
|
||||||
|
Elasticity float32
|
||||||
|
FrictionWeight float32
|
||||||
|
ElasticityWeight float32
|
||||||
|
}
|
||||||
|
|
||||||
|
func newValuePhysicalProperties() Value {
|
||||||
|
return *new(ValuePhysicalProperties)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValuePhysicalProperties) Type() Type {
|
||||||
|
return TypePhysicalProperties
|
||||||
|
}
|
||||||
|
func (t ValuePhysicalProperties) String() string {
|
||||||
|
if t.CustomPhysics {
|
||||||
|
return joinstr(
|
||||||
|
strconv.FormatFloat(float64(t.Density), 'f', -1, 32), ", ",
|
||||||
|
strconv.FormatFloat(float64(t.Friction), 'f', -1, 32), ", ",
|
||||||
|
strconv.FormatFloat(float64(t.Elasticity), 'f', -1, 32), ", ",
|
||||||
|
strconv.FormatFloat(float64(t.FrictionWeight), 'f', -1, 32), ", ",
|
||||||
|
strconv.FormatFloat(float64(t.ElasticityWeight), 'f', -1, 32),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return "nil"
|
||||||
|
}
|
||||||
|
func (t ValuePhysicalProperties) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueColor3uint8 struct {
|
||||||
|
R, G, B byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func newValueColor3uint8() Value {
|
||||||
|
return *new(ValueColor3uint8)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueColor3uint8) Type() Type {
|
||||||
|
return TypeColor3uint8
|
||||||
|
}
|
||||||
|
func (t ValueColor3uint8) String() string {
|
||||||
|
return joinstr(
|
||||||
|
strconv.FormatUint(uint64(t.R), 10),
|
||||||
|
", ",
|
||||||
|
strconv.FormatUint(uint64(t.G), 10),
|
||||||
|
", ",
|
||||||
|
strconv.FormatUint(uint64(t.B), 10),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func (t ValueColor3uint8) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueInt64 int64
|
||||||
|
|
||||||
|
func newValueInt64() Value {
|
||||||
|
return *new(ValueInt64)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueInt64) Type() Type {
|
||||||
|
return TypeInt64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t ValueInt64) String() string {
|
||||||
|
return strconv.FormatInt(int64(t), 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t ValueInt64) Copy() Value {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
type ValueSharedString []byte
|
||||||
|
|
||||||
|
func newValueSharedString() Value {
|
||||||
|
return make(ValueSharedString, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ValueSharedString) Type() Type {
|
||||||
|
return TypeSharedString
|
||||||
|
}
|
||||||
|
func (t ValueSharedString) String() string {
|
||||||
|
return string(t)
|
||||||
|
}
|
||||||
|
func (t ValueSharedString) Copy() Value {
|
||||||
|
c := make(ValueSharedString, len(t))
|
||||||
|
copy(c, t)
|
||||||
|
return c
|
||||||
|
}
|
1597
vendor/git.itzana.me/itzaname/rbxfile/xml/codec.go
generated
vendored
Normal file
1597
vendor/git.itzana.me/itzaname/rbxfile/xml/codec.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1246
vendor/git.itzana.me/itzaname/rbxfile/xml/document.go
generated
vendored
Normal file
1246
vendor/git.itzana.me/itzaname/rbxfile/xml/document.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
102
vendor/git.itzana.me/itzaname/rbxfile/xml/format.go
generated
vendored
Normal file
102
vendor/git.itzana.me/itzaname/rbxfile/xml/format.go
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package xml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"git.itzana.me/itzaname/rbxapi"
|
||||||
|
"git.itzana.me/itzaname/rbxfile"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Decoder decodes a Document to a generic rbxfile.Root structure.
|
||||||
|
type Decoder interface {
|
||||||
|
Decode(document *Document) (root *rbxfile.Root, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encoder encodes a rbxfile.Root structure to a Document.
|
||||||
|
type Encoder interface {
|
||||||
|
Encode(root *rbxfile.Root) (document *Document, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serializer implements functions that decode and encode directly between
|
||||||
|
// byte streams and rbxfile Root structures.
|
||||||
|
type Serializer struct {
|
||||||
|
Decoder Decoder
|
||||||
|
Encoder Encoder
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSerializer returns a new Serializer with a specified decoder and
|
||||||
|
// encoder. If either value is nil, the default RobloxCodec will be used in
|
||||||
|
// its place.
|
||||||
|
func NewSerializer(d Decoder, e Encoder) Serializer {
|
||||||
|
s := Serializer{
|
||||||
|
Decoder: d,
|
||||||
|
Encoder: e,
|
||||||
|
}
|
||||||
|
|
||||||
|
if d == nil || e == nil {
|
||||||
|
var codec RobloxCodec
|
||||||
|
|
||||||
|
if d == nil {
|
||||||
|
s.Decoder = codec
|
||||||
|
}
|
||||||
|
if e == nil {
|
||||||
|
s.Encoder = codec
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deserialize decodes data from r into a Root structure using the specified
|
||||||
|
// decoder.
|
||||||
|
func (s Serializer) Deserialize(r io.Reader) (root *rbxfile.Root, err error) {
|
||||||
|
if s.Decoder == nil {
|
||||||
|
return nil, errors.New("a decoder has not been not specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
document := new(Document)
|
||||||
|
|
||||||
|
if _, err = document.ReadFrom(r); err != nil {
|
||||||
|
return nil, errors.New("error parsing document: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
root, err = s.Decoder.Decode(document)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("error decoding data: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return root, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serialize encodes data from a Root structure to w using the specified
|
||||||
|
// encoder.
|
||||||
|
func (s Serializer) Serialize(w io.Writer, root *rbxfile.Root) (err error) {
|
||||||
|
if s.Encoder == nil {
|
||||||
|
return errors.New("an encoder has not been not specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
document, err := s.Encoder.Encode(root)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("error encoding data: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err = document.WriteTo(w); err != nil {
|
||||||
|
return errors.New("error encoding format: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deserialize decodes data from r into a Root structure using the default
|
||||||
|
// decoder. An optional API can be given to ensure more correct data.
|
||||||
|
func Deserialize(r io.Reader, api rbxapi.Root) (root *rbxfile.Root, err error) {
|
||||||
|
codec := RobloxCodec{API: api}
|
||||||
|
return NewSerializer(codec, codec).Deserialize(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serialize encodes data from a Root structure to w using the default
|
||||||
|
// encoder. An optional API can be given to ensure more correct data.
|
||||||
|
func Serialize(w io.Writer, api rbxapi.Root, root *rbxfile.Root) (err error) {
|
||||||
|
codec := RobloxCodec{API: api}
|
||||||
|
return NewSerializer(codec, codec).Serialize(w, root)
|
||||||
|
}
|
9
vendor/github.com/google/uuid/.travis.yml
generated
vendored
Normal file
9
vendor/github.com/google/uuid/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
language: go
|
||||||
|
|
||||||
|
go:
|
||||||
|
- 1.4.3
|
||||||
|
- 1.5.3
|
||||||
|
- tip
|
||||||
|
|
||||||
|
script:
|
||||||
|
- go test -v ./...
|
10
vendor/github.com/google/uuid/CONTRIBUTING.md
generated
vendored
Normal file
10
vendor/github.com/google/uuid/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# How to contribute
|
||||||
|
|
||||||
|
We definitely welcome patches and contribution to this project!
|
||||||
|
|
||||||
|
### Legal requirements
|
||||||
|
|
||||||
|
In order to protect both you and ourselves, you will need to sign the
|
||||||
|
[Contributor License Agreement](https://cla.developers.google.com/clas).
|
||||||
|
|
||||||
|
You may have already signed it for other Google projects.
|
9
vendor/github.com/google/uuid/CONTRIBUTORS
generated
vendored
Normal file
9
vendor/github.com/google/uuid/CONTRIBUTORS
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
Paul Borman <borman@google.com>
|
||||||
|
bmatsuo
|
||||||
|
shawnps
|
||||||
|
theory
|
||||||
|
jboverfelt
|
||||||
|
dsymonds
|
||||||
|
cd1
|
||||||
|
wallclockbuilder
|
||||||
|
dansouza
|
27
vendor/github.com/google/uuid/LICENSE
generated
vendored
Normal file
27
vendor/github.com/google/uuid/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2009,2014 Google Inc. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
19
vendor/github.com/google/uuid/README.md
generated
vendored
Normal file
19
vendor/github.com/google/uuid/README.md
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# uuid ![build status](https://travis-ci.org/google/uuid.svg?branch=master)
|
||||||
|
The uuid package generates and inspects UUIDs based on
|
||||||
|
[RFC 4122](http://tools.ietf.org/html/rfc4122)
|
||||||
|
and DCE 1.1: Authentication and Security Services.
|
||||||
|
|
||||||
|
This package is based on the github.com/pborman/uuid package (previously named
|
||||||
|
code.google.com/p/go-uuid). It differs from these earlier packages in that
|
||||||
|
a UUID is a 16 byte array rather than a byte slice. One loss due to this
|
||||||
|
change is the ability to represent an invalid UUID (vs a NIL UUID).
|
||||||
|
|
||||||
|
###### Install
|
||||||
|
`go get github.com/google/uuid`
|
||||||
|
|
||||||
|
###### Documentation
|
||||||
|
[![GoDoc](https://godoc.org/github.com/google/uuid?status.svg)](http://godoc.org/github.com/google/uuid)
|
||||||
|
|
||||||
|
Full `go doc` style documentation for the package can be viewed online without
|
||||||
|
installing this package by using the GoDoc site here:
|
||||||
|
http://pkg.go.dev/github.com/google/uuid
|
80
vendor/github.com/google/uuid/dce.go
generated
vendored
Normal file
80
vendor/github.com/google/uuid/dce.go
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// Copyright 2016 Google Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package uuid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Domain represents a Version 2 domain
|
||||||
|
type Domain byte
|
||||||
|
|
||||||
|
// Domain constants for DCE Security (Version 2) UUIDs.
|
||||||
|
const (
|
||||||
|
Person = Domain(0)
|
||||||
|
Group = Domain(1)
|
||||||
|
Org = Domain(2)
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewDCESecurity returns a DCE Security (Version 2) UUID.
|
||||||
|
//
|
||||||
|
// The domain should be one of Person, Group or Org.
|
||||||
|
// On a POSIX system the id should be the users UID for the Person
|
||||||
|
// domain and the users GID for the Group. The meaning of id for
|
||||||
|
// the domain Org or on non-POSIX systems is site defined.
|
||||||
|
//
|
||||||
|
// For a given domain/id pair the same token may be returned for up to
|
||||||
|
// 7 minutes and 10 seconds.
|
||||||
|
func NewDCESecurity(domain Domain, id uint32) (UUID, error) {
|
||||||
|
uuid, err := NewUUID()
|
||||||
|
if err == nil {
|
||||||
|
uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2
|
||||||
|
uuid[9] = byte(domain)
|
||||||
|
binary.BigEndian.PutUint32(uuid[0:], id)
|
||||||
|
}
|
||||||
|
return uuid, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDCEPerson returns a DCE Security (Version 2) UUID in the person
|
||||||
|
// domain with the id returned by os.Getuid.
|
||||||
|
//
|
||||||
|
// NewDCESecurity(Person, uint32(os.Getuid()))
|
||||||
|
func NewDCEPerson() (UUID, error) {
|
||||||
|
return NewDCESecurity(Person, uint32(os.Getuid()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDCEGroup returns a DCE Security (Version 2) UUID in the group
|
||||||
|
// domain with the id returned by os.Getgid.
|
||||||
|
//
|
||||||
|
// NewDCESecurity(Group, uint32(os.Getgid()))
|
||||||
|
func NewDCEGroup() (UUID, error) {
|
||||||
|
return NewDCESecurity(Group, uint32(os.Getgid()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Domain returns the domain for a Version 2 UUID. Domains are only defined
|
||||||
|
// for Version 2 UUIDs.
|
||||||
|
func (uuid UUID) Domain() Domain {
|
||||||
|
return Domain(uuid[9])
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2
|
||||||
|
// UUIDs.
|
||||||
|
func (uuid UUID) ID() uint32 {
|
||||||
|
return binary.BigEndian.Uint32(uuid[0:4])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Domain) String() string {
|
||||||
|
switch d {
|
||||||
|
case Person:
|
||||||
|
return "Person"
|
||||||
|
case Group:
|
||||||
|
return "Group"
|
||||||
|
case Org:
|
||||||
|
return "Org"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Domain%d", int(d))
|
||||||
|
}
|
12
vendor/github.com/google/uuid/doc.go
generated
vendored
Normal file
12
vendor/github.com/google/uuid/doc.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright 2016 Google Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package uuid generates and inspects UUIDs.
|
||||||
|
//
|
||||||
|
// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security
|
||||||
|
// Services.
|
||||||
|
//
|
||||||
|
// A UUID is a 16 byte (128 bit) array. UUIDs may be used as keys to
|
||||||
|
// maps or compared directly.
|
||||||
|
package uuid
|
1
vendor/github.com/google/uuid/go.mod
generated
vendored
Normal file
1
vendor/github.com/google/uuid/go.mod
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
module github.com/google/uuid
|
53
vendor/github.com/google/uuid/hash.go
generated
vendored
Normal file
53
vendor/github.com/google/uuid/hash.go
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright 2016 Google Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package uuid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"crypto/sha1"
|
||||||
|
"hash"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Well known namespace IDs and UUIDs
|
||||||
|
var (
|
||||||
|
NameSpaceDNS = Must(Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8"))
|
||||||
|
NameSpaceURL = Must(Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8"))
|
||||||
|
NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8"))
|
||||||
|
NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8"))
|
||||||
|
Nil UUID // empty UUID, all zeros
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewHash returns a new UUID derived from the hash of space concatenated with
|
||||||
|
// data generated by h. The hash should be at least 16 byte in length. The
|
||||||
|
// first 16 bytes of the hash are used to form the UUID. The version of the
|
||||||
|
// UUID will be the lower 4 bits of version. NewHash is used to implement
|
||||||
|
// NewMD5 and NewSHA1.
|
||||||
|
func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
|
||||||
|
h.Reset()
|
||||||
|
h.Write(space[:])
|
||||||
|
h.Write(data)
|
||||||
|
s := h.Sum(nil)
|
||||||
|
var uuid UUID
|
||||||
|
copy(uuid[:], s)
|
||||||
|
uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4)
|
||||||
|
uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant
|
||||||
|
return uuid
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMD5 returns a new MD5 (Version 3) UUID based on the
|
||||||
|
// supplied name space and data. It is the same as calling:
|
||||||
|
//
|
||||||
|
// NewHash(md5.New(), space, data, 3)
|
||||||
|
func NewMD5(space UUID, data []byte) UUID {
|
||||||
|
return NewHash(md5.New(), space, data, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSHA1 returns a new SHA1 (Version 5) UUID based on the
|
||||||
|
// supplied name space and data. It is the same as calling:
|
||||||
|
//
|
||||||
|
// NewHash(sha1.New(), space, data, 5)
|
||||||
|
func NewSHA1(space UUID, data []byte) UUID {
|
||||||
|
return NewHash(sha1.New(), space, data, 5)
|
||||||
|
}
|
38
vendor/github.com/google/uuid/marshal.go
generated
vendored
Normal file
38
vendor/github.com/google/uuid/marshal.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright 2016 Google Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package uuid
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// MarshalText implements encoding.TextMarshaler.
|
||||||
|
func (uuid UUID) MarshalText() ([]byte, error) {
|
||||||
|
var js [36]byte
|
||||||
|
encodeHex(js[:], uuid)
|
||||||
|
return js[:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||||
|
func (uuid *UUID) UnmarshalText(data []byte) error {
|
||||||
|
id, err := ParseBytes(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*uuid = id
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBinary implements encoding.BinaryMarshaler.
|
||||||
|
func (uuid UUID) MarshalBinary() ([]byte, error) {
|
||||||
|
return uuid[:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBinary implements encoding.BinaryUnmarshaler.
|
||||||
|
func (uuid *UUID) UnmarshalBinary(data []byte) error {
|
||||||
|
if len(data) != 16 {
|
||||||
|
return fmt.Errorf("invalid UUID (got %d bytes)", len(data))
|
||||||
|
}
|
||||||
|
copy(uuid[:], data)
|
||||||
|
return nil
|
||||||
|
}
|
90
vendor/github.com/google/uuid/node.go
generated
vendored
Normal file
90
vendor/github.com/google/uuid/node.go
generated
vendored
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
// Copyright 2016 Google Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package uuid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
nodeMu sync.Mutex
|
||||||
|
ifname string // name of interface being used
|
||||||
|
nodeID [6]byte // hardware for version 1 UUIDs
|
||||||
|
zeroID [6]byte // nodeID with only 0's
|
||||||
|
)
|
||||||
|
|
||||||
|
// NodeInterface returns the name of the interface from which the NodeID was
|
||||||
|
// derived. The interface "user" is returned if the NodeID was set by
|
||||||
|
// SetNodeID.
|
||||||
|
func NodeInterface() string {
|
||||||
|
defer nodeMu.Unlock()
|
||||||
|
nodeMu.Lock()
|
||||||
|
return ifname
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.
|
||||||
|
// If name is "" then the first usable interface found will be used or a random
|
||||||
|
// Node ID will be generated. If a named interface cannot be found then false
|
||||||
|
// is returned.
|
||||||
|
//
|
||||||
|
// SetNodeInterface never fails when name is "".
|
||||||
|
func SetNodeInterface(name string) bool {
|
||||||
|
defer nodeMu.Unlock()
|
||||||
|
nodeMu.Lock()
|
||||||
|
return setNodeInterface(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setNodeInterface(name string) bool {
|
||||||
|
iname, addr := getHardwareInterface(name) // null implementation for js
|
||||||
|
if iname != "" && addr != nil {
|
||||||
|
ifname = iname
|
||||||
|
copy(nodeID[:], addr)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// We found no interfaces with a valid hardware address. If name
|
||||||
|
// does not specify a specific interface generate a random Node ID
|
||||||
|
// (section 4.1.6)
|
||||||
|
if name == "" {
|
||||||
|
ifname = "random"
|
||||||
|
randomBits(nodeID[:])
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// NodeID returns a slice of a copy of the current Node ID, setting the Node ID
|
||||||
|
// if not already set.
|
||||||
|
func NodeID() []byte {
|
||||||
|
defer nodeMu.Unlock()
|
||||||
|
nodeMu.Lock()
|
||||||
|
if nodeID == zeroID {
|
||||||
|
setNodeInterface("")
|
||||||
|
}
|
||||||
|
nid := nodeID
|
||||||
|
return nid[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes
|
||||||
|
// of id are used. If id is less than 6 bytes then false is returned and the
|
||||||
|
// Node ID is not set.
|
||||||
|
func SetNodeID(id []byte) bool {
|
||||||
|
if len(id) < 6 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
defer nodeMu.Unlock()
|
||||||
|
nodeMu.Lock()
|
||||||
|
copy(nodeID[:], id)
|
||||||
|
ifname = "user"
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is
|
||||||
|
// not valid. The NodeID is only well defined for version 1 and 2 UUIDs.
|
||||||
|
func (uuid UUID) NodeID() []byte {
|
||||||
|
var node [6]byte
|
||||||
|
copy(node[:], uuid[10:])
|
||||||
|
return node[:]
|
||||||
|
}
|
12
vendor/github.com/google/uuid/node_js.go
generated
vendored
Normal file
12
vendor/github.com/google/uuid/node_js.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright 2017 Google Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build js
|
||||||
|
|
||||||
|
package uuid
|
||||||
|
|
||||||
|
// getHardwareInterface returns nil values for the JS version of the code.
|
||||||
|
// This remvoves the "net" dependency, because it is not used in the browser.
|
||||||
|
// Using the "net" library inflates the size of the transpiled JS code by 673k bytes.
|
||||||
|
func getHardwareInterface(name string) (string, []byte) { return "", nil }
|
33
vendor/github.com/google/uuid/node_net.go
generated
vendored
Normal file
33
vendor/github.com/google/uuid/node_net.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2017 Google Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !js
|
||||||
|
|
||||||
|
package uuid
|
||||||
|
|
||||||
|
import "net"
|
||||||
|
|
||||||
|
var interfaces []net.Interface // cached list of interfaces
|
||||||
|
|
||||||
|
// getHardwareInterface returns the name and hardware address of interface name.
|
||||||
|
// If name is "" then the name and hardware address of one of the system's
|
||||||
|
// interfaces is returned. If no interfaces are found (name does not exist or
|
||||||
|
// there are no interfaces) then "", nil is returned.
|
||||||
|
//
|
||||||
|
// Only addresses of at least 6 bytes are returned.
|
||||||
|
func getHardwareInterface(name string) (string, []byte) {
|
||||||
|
if interfaces == nil {
|
||||||
|
var err error
|
||||||
|
interfaces, err = net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, ifs := range interfaces {
|
||||||
|
if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) {
|
||||||
|
return ifs.Name, ifs.HardwareAddr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
|
}
|
59
vendor/github.com/google/uuid/sql.go
generated
vendored
Normal file
59
vendor/github.com/google/uuid/sql.go
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// Copyright 2016 Google Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package uuid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql/driver"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Scan implements sql.Scanner so UUIDs can be read from databases transparently
|
||||||
|
// Currently, database types that map to string and []byte are supported. Please
|
||||||
|
// consult database-specific driver documentation for matching types.
|
||||||
|
func (uuid *UUID) Scan(src interface{}) error {
|
||||||
|
switch src := src.(type) {
|
||||||
|
case nil:
|
||||||
|
return nil
|
||||||
|
|
||||||
|
case string:
|
||||||
|
// if an empty UUID comes from a table, we return a null UUID
|
||||||
|
if src == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// see Parse for required string format
|
||||||
|
u, err := Parse(src)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Scan: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*uuid = u
|
||||||
|
|
||||||
|
case []byte:
|
||||||
|
// if an empty UUID comes from a table, we return a null UUID
|
||||||
|
if len(src) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// assumes a simple slice of bytes if 16 bytes
|
||||||
|
// otherwise attempts to parse
|
||||||
|
if len(src) != 16 {
|
||||||
|
return uuid.Scan(string(src))
|
||||||
|
}
|
||||||
|
copy((*uuid)[:], src)
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Scan: unable to scan type %T into UUID", src)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value implements sql.Valuer so that UUIDs can be written to databases
|
||||||
|
// transparently. Currently, UUIDs map to strings. Please consult
|
||||||
|
// database-specific driver documentation for matching types.
|
||||||
|
func (uuid UUID) Value() (driver.Value, error) {
|
||||||
|
return uuid.String(), nil
|
||||||
|
}
|
123
vendor/github.com/google/uuid/time.go
generated
vendored
Normal file
123
vendor/github.com/google/uuid/time.go
generated
vendored
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
// Copyright 2016 Google Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package uuid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Time represents a time as the number of 100's of nanoseconds since 15 Oct
|
||||||
|
// 1582.
|
||||||
|
type Time int64
|
||||||
|
|
||||||
|
const (
|
||||||
|
lillian = 2299160 // Julian day of 15 Oct 1582
|
||||||
|
unix = 2440587 // Julian day of 1 Jan 1970
|
||||||
|
epoch = unix - lillian // Days between epochs
|
||||||
|
g1582 = epoch * 86400 // seconds between epochs
|
||||||
|
g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
timeMu sync.Mutex
|
||||||
|
lasttime uint64 // last time we returned
|
||||||
|
clockSeq uint16 // clock sequence for this run
|
||||||
|
|
||||||
|
timeNow = time.Now // for testing
|
||||||
|
)
|
||||||
|
|
||||||
|
// UnixTime converts t the number of seconds and nanoseconds using the Unix
|
||||||
|
// epoch of 1 Jan 1970.
|
||||||
|
func (t Time) UnixTime() (sec, nsec int64) {
|
||||||
|
sec = int64(t - g1582ns100)
|
||||||
|
nsec = (sec % 10000000) * 100
|
||||||
|
sec /= 10000000
|
||||||
|
return sec, nsec
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and
|
||||||
|
// clock sequence as well as adjusting the clock sequence as needed. An error
|
||||||
|
// is returned if the current time cannot be determined.
|
||||||
|
func GetTime() (Time, uint16, error) {
|
||||||
|
defer timeMu.Unlock()
|
||||||
|
timeMu.Lock()
|
||||||
|
return getTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTime() (Time, uint16, error) {
|
||||||
|
t := timeNow()
|
||||||
|
|
||||||
|
// If we don't have a clock sequence already, set one.
|
||||||
|
if clockSeq == 0 {
|
||||||
|
setClockSequence(-1)
|
||||||
|
}
|
||||||
|
now := uint64(t.UnixNano()/100) + g1582ns100
|
||||||
|
|
||||||
|
// If time has gone backwards with this clock sequence then we
|
||||||
|
// increment the clock sequence
|
||||||
|
if now <= lasttime {
|
||||||
|
clockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000
|
||||||
|
}
|
||||||
|
lasttime = now
|
||||||
|
return Time(now), clockSeq, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClockSequence returns the current clock sequence, generating one if not
|
||||||
|
// already set. The clock sequence is only used for Version 1 UUIDs.
|
||||||
|
//
|
||||||
|
// The uuid package does not use global static storage for the clock sequence or
|
||||||
|
// the last time a UUID was generated. Unless SetClockSequence is used, a new
|
||||||
|
// random clock sequence is generated the first time a clock sequence is
|
||||||
|
// requested by ClockSequence, GetTime, or NewUUID. (section 4.2.1.1)
|
||||||
|
func ClockSequence() int {
|
||||||
|
defer timeMu.Unlock()
|
||||||
|
timeMu.Lock()
|
||||||
|
return clockSequence()
|
||||||
|
}
|
||||||
|
|
||||||
|
func clockSequence() int {
|
||||||
|
if clockSeq == 0 {
|
||||||
|
setClockSequence(-1)
|
||||||
|
}
|
||||||
|
return int(clockSeq & 0x3fff)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetClockSequence sets the clock sequence to the lower 14 bits of seq. Setting to
|
||||||
|
// -1 causes a new sequence to be generated.
|
||||||
|
func SetClockSequence(seq int) {
|
||||||
|
defer timeMu.Unlock()
|
||||||
|
timeMu.Lock()
|
||||||
|
setClockSequence(seq)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setClockSequence(seq int) {
|
||||||
|
if seq == -1 {
|
||||||
|
var b [2]byte
|
||||||
|
randomBits(b[:]) // clock sequence
|
||||||
|
seq = int(b[0])<<8 | int(b[1])
|
||||||
|
}
|
||||||
|
oldSeq := clockSeq
|
||||||
|
clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant
|
||||||
|
if oldSeq != clockSeq {
|
||||||
|
lasttime = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in
|
||||||
|
// uuid. The time is only defined for version 1 and 2 UUIDs.
|
||||||
|
func (uuid UUID) Time() Time {
|
||||||
|
time := int64(binary.BigEndian.Uint32(uuid[0:4]))
|
||||||
|
time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32
|
||||||
|
time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48
|
||||||
|
return Time(time)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClockSequence returns the clock sequence encoded in uuid.
|
||||||
|
// The clock sequence is only well defined for version 1 and 2 UUIDs.
|
||||||
|
func (uuid UUID) ClockSequence() int {
|
||||||
|
return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff
|
||||||
|
}
|
43
vendor/github.com/google/uuid/util.go
generated
vendored
Normal file
43
vendor/github.com/google/uuid/util.go
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright 2016 Google Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package uuid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// randomBits completely fills slice b with random data.
|
||||||
|
func randomBits(b []byte) {
|
||||||
|
if _, err := io.ReadFull(rander, b); err != nil {
|
||||||
|
panic(err.Error()) // rand should never fail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// xvalues returns the value of a byte as a hexadecimal digit or 255.
|
||||||
|
var xvalues = [256]byte{
|
||||||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
|
||||||
|
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
}
|
||||||
|
|
||||||
|
// xtob converts hex characters x1 and x2 into a byte.
|
||||||
|
func xtob(x1, x2 byte) (byte, bool) {
|
||||||
|
b1 := xvalues[x1]
|
||||||
|
b2 := xvalues[x2]
|
||||||
|
return (b1 << 4) | b2, b1 != 255 && b2 != 255
|
||||||
|
}
|
245
vendor/github.com/google/uuid/uuid.go
generated
vendored
Normal file
245
vendor/github.com/google/uuid/uuid.go
generated
vendored
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
// Copyright 2018 Google Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package uuid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC
|
||||||
|
// 4122.
|
||||||
|
type UUID [16]byte
|
||||||
|
|
||||||
|
// A Version represents a UUID's version.
|
||||||
|
type Version byte
|
||||||
|
|
||||||
|
// A Variant represents a UUID's variant.
|
||||||
|
type Variant byte
|
||||||
|
|
||||||
|
// Constants returned by Variant.
|
||||||
|
const (
|
||||||
|
Invalid = Variant(iota) // Invalid UUID
|
||||||
|
RFC4122 // The variant specified in RFC4122
|
||||||
|
Reserved // Reserved, NCS backward compatibility.
|
||||||
|
Microsoft // Reserved, Microsoft Corporation backward compatibility.
|
||||||
|
Future // Reserved for future definition.
|
||||||
|
)
|
||||||
|
|
||||||
|
var rander = rand.Reader // random function
|
||||||
|
|
||||||
|
// Parse decodes s into a UUID or returns an error. Both the standard UUID
|
||||||
|
// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
|
||||||
|
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the
|
||||||
|
// Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex
|
||||||
|
// encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
|
||||||
|
func Parse(s string) (UUID, error) {
|
||||||
|
var uuid UUID
|
||||||
|
switch len(s) {
|
||||||
|
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||||
|
case 36:
|
||||||
|
|
||||||
|
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||||
|
case 36 + 9:
|
||||||
|
if strings.ToLower(s[:9]) != "urn:uuid:" {
|
||||||
|
return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9])
|
||||||
|
}
|
||||||
|
s = s[9:]
|
||||||
|
|
||||||
|
// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
|
||||||
|
case 36 + 2:
|
||||||
|
s = s[1:]
|
||||||
|
|
||||||
|
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
case 32:
|
||||||
|
var ok bool
|
||||||
|
for i := range uuid {
|
||||||
|
uuid[i], ok = xtob(s[i*2], s[i*2+1])
|
||||||
|
if !ok {
|
||||||
|
return uuid, errors.New("invalid UUID format")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uuid, nil
|
||||||
|
default:
|
||||||
|
return uuid, fmt.Errorf("invalid UUID length: %d", len(s))
|
||||||
|
}
|
||||||
|
// s is now at least 36 bytes long
|
||||||
|
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||||
|
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
|
||||||
|
return uuid, errors.New("invalid UUID format")
|
||||||
|
}
|
||||||
|
for i, x := range [16]int{
|
||||||
|
0, 2, 4, 6,
|
||||||
|
9, 11,
|
||||||
|
14, 16,
|
||||||
|
19, 21,
|
||||||
|
24, 26, 28, 30, 32, 34} {
|
||||||
|
v, ok := xtob(s[x], s[x+1])
|
||||||
|
if !ok {
|
||||||
|
return uuid, errors.New("invalid UUID format")
|
||||||
|
}
|
||||||
|
uuid[i] = v
|
||||||
|
}
|
||||||
|
return uuid, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseBytes is like Parse, except it parses a byte slice instead of a string.
|
||||||
|
func ParseBytes(b []byte) (UUID, error) {
|
||||||
|
var uuid UUID
|
||||||
|
switch len(b) {
|
||||||
|
case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||||
|
case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||||
|
if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) {
|
||||||
|
return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9])
|
||||||
|
}
|
||||||
|
b = b[9:]
|
||||||
|
case 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
|
||||||
|
b = b[1:]
|
||||||
|
case 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
var ok bool
|
||||||
|
for i := 0; i < 32; i += 2 {
|
||||||
|
uuid[i/2], ok = xtob(b[i], b[i+1])
|
||||||
|
if !ok {
|
||||||
|
return uuid, errors.New("invalid UUID format")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uuid, nil
|
||||||
|
default:
|
||||||
|
return uuid, fmt.Errorf("invalid UUID length: %d", len(b))
|
||||||
|
}
|
||||||
|
// s is now at least 36 bytes long
|
||||||
|
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||||
|
if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' {
|
||||||
|
return uuid, errors.New("invalid UUID format")
|
||||||
|
}
|
||||||
|
for i, x := range [16]int{
|
||||||
|
0, 2, 4, 6,
|
||||||
|
9, 11,
|
||||||
|
14, 16,
|
||||||
|
19, 21,
|
||||||
|
24, 26, 28, 30, 32, 34} {
|
||||||
|
v, ok := xtob(b[x], b[x+1])
|
||||||
|
if !ok {
|
||||||
|
return uuid, errors.New("invalid UUID format")
|
||||||
|
}
|
||||||
|
uuid[i] = v
|
||||||
|
}
|
||||||
|
return uuid, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustParse is like Parse but panics if the string cannot be parsed.
|
||||||
|
// It simplifies safe initialization of global variables holding compiled UUIDs.
|
||||||
|
func MustParse(s string) UUID {
|
||||||
|
uuid, err := Parse(s)
|
||||||
|
if err != nil {
|
||||||
|
panic(`uuid: Parse(` + s + `): ` + err.Error())
|
||||||
|
}
|
||||||
|
return uuid
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromBytes creates a new UUID from a byte slice. Returns an error if the slice
|
||||||
|
// does not have a length of 16. The bytes are copied from the slice.
|
||||||
|
func FromBytes(b []byte) (uuid UUID, err error) {
|
||||||
|
err = uuid.UnmarshalBinary(b)
|
||||||
|
return uuid, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must returns uuid if err is nil and panics otherwise.
|
||||||
|
func Must(uuid UUID, err error) UUID {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return uuid
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||||
|
// , or "" if uuid is invalid.
|
||||||
|
func (uuid UUID) String() string {
|
||||||
|
var buf [36]byte
|
||||||
|
encodeHex(buf[:], uuid)
|
||||||
|
return string(buf[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// URN returns the RFC 2141 URN form of uuid,
|
||||||
|
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid.
|
||||||
|
func (uuid UUID) URN() string {
|
||||||
|
var buf [36 + 9]byte
|
||||||
|
copy(buf[:], "urn:uuid:")
|
||||||
|
encodeHex(buf[9:], uuid)
|
||||||
|
return string(buf[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeHex(dst []byte, uuid UUID) {
|
||||||
|
hex.Encode(dst, uuid[:4])
|
||||||
|
dst[8] = '-'
|
||||||
|
hex.Encode(dst[9:13], uuid[4:6])
|
||||||
|
dst[13] = '-'
|
||||||
|
hex.Encode(dst[14:18], uuid[6:8])
|
||||||
|
dst[18] = '-'
|
||||||
|
hex.Encode(dst[19:23], uuid[8:10])
|
||||||
|
dst[23] = '-'
|
||||||
|
hex.Encode(dst[24:], uuid[10:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variant returns the variant encoded in uuid.
|
||||||
|
func (uuid UUID) Variant() Variant {
|
||||||
|
switch {
|
||||||
|
case (uuid[8] & 0xc0) == 0x80:
|
||||||
|
return RFC4122
|
||||||
|
case (uuid[8] & 0xe0) == 0xc0:
|
||||||
|
return Microsoft
|
||||||
|
case (uuid[8] & 0xe0) == 0xe0:
|
||||||
|
return Future
|
||||||
|
default:
|
||||||
|
return Reserved
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version returns the version of uuid.
|
||||||
|
func (uuid UUID) Version() Version {
|
||||||
|
return Version(uuid[6] >> 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Version) String() string {
|
||||||
|
if v > 15 {
|
||||||
|
return fmt.Sprintf("BAD_VERSION_%d", v)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("VERSION_%d", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Variant) String() string {
|
||||||
|
switch v {
|
||||||
|
case RFC4122:
|
||||||
|
return "RFC4122"
|
||||||
|
case Reserved:
|
||||||
|
return "Reserved"
|
||||||
|
case Microsoft:
|
||||||
|
return "Microsoft"
|
||||||
|
case Future:
|
||||||
|
return "Future"
|
||||||
|
case Invalid:
|
||||||
|
return "Invalid"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("BadVariant%d", int(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRand sets the random number generator to r, which implements io.Reader.
|
||||||
|
// If r.Read returns an error when the package requests random data then
|
||||||
|
// a panic will be issued.
|
||||||
|
//
|
||||||
|
// Calling SetRand with nil sets the random number generator to the default
|
||||||
|
// generator.
|
||||||
|
func SetRand(r io.Reader) {
|
||||||
|
if r == nil {
|
||||||
|
rander = rand.Reader
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rander = r
|
||||||
|
}
|
44
vendor/github.com/google/uuid/version1.go
generated
vendored
Normal file
44
vendor/github.com/google/uuid/version1.go
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright 2016 Google Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package uuid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewUUID returns a Version 1 UUID based on the current NodeID and clock
|
||||||
|
// sequence, and the current time. If the NodeID has not been set by SetNodeID
|
||||||
|
// or SetNodeInterface then it will be set automatically. If the NodeID cannot
|
||||||
|
// be set NewUUID returns nil. If clock sequence has not been set by
|
||||||
|
// SetClockSequence then it will be set automatically. If GetTime fails to
|
||||||
|
// return the current NewUUID returns nil and an error.
|
||||||
|
//
|
||||||
|
// In most cases, New should be used.
|
||||||
|
func NewUUID() (UUID, error) {
|
||||||
|
var uuid UUID
|
||||||
|
now, seq, err := GetTime()
|
||||||
|
if err != nil {
|
||||||
|
return uuid, err
|
||||||
|
}
|
||||||
|
|
||||||
|
timeLow := uint32(now & 0xffffffff)
|
||||||
|
timeMid := uint16((now >> 32) & 0xffff)
|
||||||
|
timeHi := uint16((now >> 48) & 0x0fff)
|
||||||
|
timeHi |= 0x1000 // Version 1
|
||||||
|
|
||||||
|
binary.BigEndian.PutUint32(uuid[0:], timeLow)
|
||||||
|
binary.BigEndian.PutUint16(uuid[4:], timeMid)
|
||||||
|
binary.BigEndian.PutUint16(uuid[6:], timeHi)
|
||||||
|
binary.BigEndian.PutUint16(uuid[8:], seq)
|
||||||
|
|
||||||
|
nodeMu.Lock()
|
||||||
|
if nodeID == zeroID {
|
||||||
|
setNodeInterface("")
|
||||||
|
}
|
||||||
|
copy(uuid[10:], nodeID[:])
|
||||||
|
nodeMu.Unlock()
|
||||||
|
|
||||||
|
return uuid, nil
|
||||||
|
}
|
43
vendor/github.com/google/uuid/version4.go
generated
vendored
Normal file
43
vendor/github.com/google/uuid/version4.go
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright 2016 Google Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package uuid
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
// New creates a new random UUID or panics. New is equivalent to
|
||||||
|
// the expression
|
||||||
|
//
|
||||||
|
// uuid.Must(uuid.NewRandom())
|
||||||
|
func New() UUID {
|
||||||
|
return Must(NewRandom())
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRandom returns a Random (Version 4) UUID.
|
||||||
|
//
|
||||||
|
// The strength of the UUIDs is based on the strength of the crypto/rand
|
||||||
|
// package.
|
||||||
|
//
|
||||||
|
// A note about uniqueness derived from the UUID Wikipedia entry:
|
||||||
|
//
|
||||||
|
// Randomly generated UUIDs have 122 random bits. One's annual risk of being
|
||||||
|
// hit by a meteorite is estimated to be one chance in 17 billion, that
|
||||||
|
// means the probability is about 0.00000000006 (6 × 10−11),
|
||||||
|
// equivalent to the odds of creating a few tens of trillions of UUIDs in a
|
||||||
|
// year and having one duplicate.
|
||||||
|
func NewRandom() (UUID, error) {
|
||||||
|
return NewRandomFromReader(rander)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRandomFromReader returns a UUID based on bytes read from a given io.Reader.
|
||||||
|
func NewRandomFromReader(r io.Reader) (UUID, error) {
|
||||||
|
var uuid UUID
|
||||||
|
_, err := io.ReadFull(r, uuid[:])
|
||||||
|
if err != nil {
|
||||||
|
return Nil, err
|
||||||
|
}
|
||||||
|
uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
|
||||||
|
uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
|
||||||
|
return uuid, nil
|
||||||
|
}
|
12
vendor/modules.txt
vendored
Normal file
12
vendor/modules.txt
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# git.itzana.me/itzaname/go-roblox v1.0.1
|
||||||
|
## explicit
|
||||||
|
git.itzana.me/itzaname/go-roblox
|
||||||
|
# git.itzana.me/itzaname/rbxapi v0.1.0
|
||||||
|
git.itzana.me/itzaname/rbxapi
|
||||||
|
# git.itzana.me/itzaname/rbxfile v0.0.0-20210811000911-6fc7a2281e8d
|
||||||
|
## explicit
|
||||||
|
git.itzana.me/itzaname/rbxfile
|
||||||
|
git.itzana.me/itzaname/rbxfile/xml
|
||||||
|
# github.com/google/uuid v1.1.2
|
||||||
|
## explicit
|
||||||
|
github.com/google/uuid
|
Loading…
Reference in New Issue
Block a user