mirror of
https://wiilab.wiimart.org/wiimart/WiiSOAP
synced 2025-09-03 20:11:14 +02:00
Use title version from v3 API
This commit is contained in:
parent
9b0fc390c2
commit
54e800e5b2
47
api.go
Normal file
47
api.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
const oscAPIUrl = "https://hbb1.oscwii.org/api/v3/contents"
|
||||||
|
|
||||||
|
type OSCApp struct {
|
||||||
|
Shop Shop `json:"shop"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Shop struct {
|
||||||
|
TitleId string `json:"title_id"`
|
||||||
|
Version int `json:"title_version"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetOSCApp(titleId string) (*OSCApp, error) {
|
||||||
|
resp, err := http.Get(oscAPIUrl)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, errors.New("osc API returned non OK status code")
|
||||||
|
}
|
||||||
|
|
||||||
|
data, _ := io.ReadAll(resp.Body)
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
var apps []OSCApp
|
||||||
|
err = json.Unmarshal(data, &apps)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, app := range apps {
|
||||||
|
if app.Shop.TitleId == titleId {
|
||||||
|
return &app, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
61
ecs.go
61
ecs.go
@ -28,16 +28,13 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// TODO (Sketch): Once v3 API has proper versions, remove query to tickets table.
|
QueryOwnedTitles = `SELECT owned_titles.title_id
|
||||||
QueryOwnedTitles = `SELECT owned_titles.title_id, tickets.version
|
FROM owned_titles
|
||||||
FROM owned_titles, tickets
|
WHERE owned_titles.account_id = $1`
|
||||||
WHERE owned_titles.title_id = tickets.title_id
|
|
||||||
AND owned_titles.account_id = $1`
|
|
||||||
|
|
||||||
QueryOwnedServiceTitles = `SELECT titles.reference_id, owned_titles.date_purchased, titles.item_id
|
QueryOwnedServiceTitles = `SELECT titles.reference_id, owned_titles.date_purchased, titles.item_id
|
||||||
FROM titles, owned_titles
|
FROM titles, owned_titles
|
||||||
@ -53,13 +50,13 @@ const (
|
|||||||
SharedBalanceAmount = math.MaxInt32
|
SharedBalanceAmount = math.MaxInt32
|
||||||
|
|
||||||
// WiinoMaApplicationID is the title ID for the Japanese channel Wii no Ma.
|
// WiinoMaApplicationID is the title ID for the Japanese channel Wii no Ma.
|
||||||
WiinoMaApplicationID = "000100014843494a"
|
WiinoMaApplicationID = "000100014843494A"
|
||||||
// WiinoMaServiceTitleID is the service ID used by Wii no Ma's theatre.
|
// WiinoMaServiceTitleID is the service ID used by Wii no Ma's theatre.
|
||||||
WiinoMaServiceTitleID = "000101006843494a"
|
WiinoMaServiceTitleID = "000101006843494A"
|
||||||
)
|
)
|
||||||
|
|
||||||
// content_aes_key is the AES key that is used to encrypt title contents.
|
// contentAesKey is the AES key that is used to encrypt title contents.
|
||||||
var content_aes_key = [16]byte{0x72, 0x95, 0xDB, 0xC0, 0x47, 0x3C, 0x90, 0x0B, 0xB5, 0x94, 0x19, 0x9C, 0xB5, 0xBC, 0xD3, 0xDC}
|
var contentAesKey = [16]byte{0x72, 0x95, 0xDB, 0xC0, 0x47, 0x3C, 0x90, 0x0B, 0xB5, 0x94, 0x19, 0x9C, 0xB5, 0xBC, 0xD3, 0xDC}
|
||||||
|
|
||||||
func getBalance() Balance {
|
func getBalance() Balance {
|
||||||
return Balance{
|
return Balance{
|
||||||
@ -97,17 +94,28 @@ func listETickets(e *Envelope) {
|
|||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var titleId string
|
var titleId string
|
||||||
var version int
|
err = rows.Scan(&titleId)
|
||||||
err = rows.Scan(&titleId, &version)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error executing statement: %v\n", err)
|
log.Printf("error executing statement: %v\n", err)
|
||||||
e.Error(2, "database error", errors.New("failed to execute db operation"))
|
e.Error(2, "database error", errors.New("failed to execute db operation"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app, err := GetOSCApp(titleId)
|
||||||
|
if err != nil {
|
||||||
|
e.Error(2, "an error has occurred retrieving app metadata", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if app == nil {
|
||||||
|
// Quite possibly an app was de-listed?
|
||||||
|
e.Error(2, "title does not exist", nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
e.AddCustomType(Tickets{
|
e.AddCustomType(Tickets{
|
||||||
TitleId: titleId,
|
TitleId: titleId,
|
||||||
Version: version,
|
Version: app.Shop.Version,
|
||||||
|
|
||||||
// We do not support migration, ticket IDs, or revocation.
|
// We do not support migration, ticket IDs, or revocation.
|
||||||
TicketId: "0",
|
TicketId: "0",
|
||||||
@ -170,9 +178,9 @@ func purchaseTitle(e *Envelope) {
|
|||||||
ticketStruct.TitleID = intTitleId
|
ticketStruct.TitleID = intTitleId
|
||||||
|
|
||||||
// Title key is encrypted with the common key and current title ID
|
// Title key is encrypted with the common key and current title ID
|
||||||
ticketStruct.UpdateTitleKey(content_aes_key)
|
ticketStruct.UpdateTitleKey(contentAesKey)
|
||||||
|
|
||||||
titleId = strings.ToLower(titleId)
|
version := 0
|
||||||
if titleId == WiinoMaServiceTitleID {
|
if titleId == WiinoMaServiceTitleID {
|
||||||
// Wii no Ma needs the ticket to be in the v1 ticket format.
|
// Wii no Ma needs the ticket to be in the v1 ticket format.
|
||||||
// Update the ticket to reflect that.
|
// Update the ticket to reflect that.
|
||||||
@ -253,7 +261,20 @@ func purchaseTitle(e *Envelope) {
|
|||||||
|
|
||||||
ticket = bytes.NewBuffer(newTicket)
|
ticket = bytes.NewBuffer(newTicket)
|
||||||
} else {
|
} else {
|
||||||
// TODO: (Sketch) Validate if this title actually exists using the v3 API.
|
// Validate that this title exists.
|
||||||
|
app, err := GetOSCApp(titleId)
|
||||||
|
if err != nil {
|
||||||
|
e.Error(2, "an error has occurred retrieving app metadata", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if app == nil {
|
||||||
|
e.Error(2, "title does not exist", nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
version = app.Shop.Version
|
||||||
|
|
||||||
err = binary.Write(ticket, binary.BigEndian, ticketStruct)
|
err = binary.Write(ticket, binary.BigEndian, ticketStruct)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e.Error(2, "failed to create ticket", err)
|
e.Error(2, "failed to create ticket", err)
|
||||||
@ -262,8 +283,7 @@ func purchaseTitle(e *Envelope) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Associate the given title ID with the user.
|
// Associate the given title ID with the user.
|
||||||
// TODO (Sketch): Once v3 API has proper versions, use.
|
_, err = pool.Exec(ctx, AssociateTicketStatement, accountId, titleId, version, itemId, time.Now().UTC())
|
||||||
_, err = pool.Exec(ctx, AssociateTicketStatement, accountId, titleId, 0, itemId, time.Now().UTC())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("unexpected error purchasing: %v", err)
|
log.Printf("unexpected error purchasing: %v", err)
|
||||||
e.Error(2, "error purchasing", nil)
|
e.Error(2, "error purchasing", nil)
|
||||||
@ -309,12 +329,9 @@ func listPurchaseHistory(e *Envelope) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
titleId = strings.ToLower(titleId)
|
|
||||||
var transactions []Transactions
|
var transactions []Transactions
|
||||||
|
|
||||||
// We will query the database differently for Wii no Ma.
|
|
||||||
if titleId == WiinoMaApplicationID {
|
if titleId == WiinoMaApplicationID {
|
||||||
// Query the database for other purchased items
|
// We will query the database differently for Wii no Ma.
|
||||||
rows, err := pool.Query(ctx, QueryOwnedServiceTitles, WiinoMaServiceTitleID, accountId)
|
rows, err := pool.Query(ctx, QueryOwnedServiceTitles, WiinoMaServiceTitleID, accountId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("unexpected error querying owned service titles: %v", err)
|
log.Printf("unexpected error querying owned service titles: %v", err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user