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