@@ -0,0 +1,66 @@
|
|||||||
|
meta {
|
||||||
|
name: SearchLobbyRooms
|
||||||
|
type: http
|
||||||
|
seq: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
url: {{gameApiHost}}/game-api/api/v1.0/lobby/rooms/search
|
||||||
|
body: json
|
||||||
|
auth: none
|
||||||
|
}
|
||||||
|
|
||||||
|
headers {
|
||||||
|
accept: */*
|
||||||
|
user-agent: Arma Reforger/1.7.0.54 (Client; Windows)
|
||||||
|
}
|
||||||
|
|
||||||
|
body:json {
|
||||||
|
{
|
||||||
|
"directJoinCode": "",
|
||||||
|
"hostAddress": "",
|
||||||
|
"order": "PlayerCount",
|
||||||
|
"includePing": 1,
|
||||||
|
"scenarioId": "",
|
||||||
|
"text": "",
|
||||||
|
"ascendent": false,
|
||||||
|
"gameClientFilter": "AnyCompatible",
|
||||||
|
"accessToken": "",
|
||||||
|
"clientVersion": "1.7.0",
|
||||||
|
"platformId": "ReforgerSteam",
|
||||||
|
"gameClientType": "PLATFORM_PC",
|
||||||
|
"lightweight": true,
|
||||||
|
"from": 0,
|
||||||
|
"limit": 50,
|
||||||
|
"pingValues": [
|
||||||
|
{ "pingSiteId": "tokyo", "value": 243.56622314453126 },
|
||||||
|
{ "pingSiteId": "los_angeles", "value": 171.9037628173828 },
|
||||||
|
{ "pingSiteId": "miami", "value": 136.6873321533203 },
|
||||||
|
{ "pingSiteId": "new_york", "value": 115.14977264404297 },
|
||||||
|
{ "pingSiteId": "singapore", "value": 271.533203125 },
|
||||||
|
{ "pingSiteId": "frankfurt", "value": 24.513813018798829 },
|
||||||
|
{ "pingSiteId": "london", "value": 32.16381072998047 },
|
||||||
|
{ "pingSiteId": "sydney", "value": 296.2795104980469 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vars:pre-request {
|
||||||
|
gameApiHost: api-ar-game.bistudio.com
|
||||||
|
}
|
||||||
|
|
||||||
|
script:pre-request {
|
||||||
|
// The game sends a JSON body under a form-urlencoded content-type. Bruno keys
|
||||||
|
// body variable interpolation off content-type, so setting that header
|
||||||
|
// declaratively silently disables {{...}} substitution in the body. Instead we
|
||||||
|
// inject the token here and set the header after, once interpolation is moot.
|
||||||
|
const body = req.getBody();
|
||||||
|
body.accessToken = bru.getEnvVar("accessToken");
|
||||||
|
req.setBody(JSON.stringify(body));
|
||||||
|
req.setHeader("content-type", "application/x-www-form-urlencoded");
|
||||||
|
}
|
||||||
|
|
||||||
|
settings {
|
||||||
|
encodeUrl: true
|
||||||
|
timeout: 0
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
vars {
|
||||||
|
gameApiHost: https://api-ar-game.bistudio.com
|
||||||
|
accessToken: PASTE_JWT_HERE
|
||||||
|
}
|
||||||
@@ -67,15 +67,9 @@ func GetDependents(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
limit := parseLimit(c.Query("limit"))
|
limit := parseLimit(c.Query("limit"))
|
||||||
|
offset := parseOffset(c.Query("offset"))
|
||||||
|
|
||||||
dependents := []models.AddonSearchResult{}
|
dependents, total, err := queryRelatedAddons(addonID, "ad.addon_id", "ad.dependency_id", limit, offset)
|
||||||
err := initializers.DB.Model(&models.Addon{}).
|
|
||||||
Select("addons.id, addons.name, addons.type, addons.summary, addons.preview, addons.subscriber_count, addons.current_version_number, addons.author").
|
|
||||||
Joins("JOIN addon_dependencies ad ON ad.addon_id = addons.id").
|
|
||||||
Where("ad.dependency_id = ?", addonID).
|
|
||||||
Order("addons.subscriber_count DESC").
|
|
||||||
Limit(limit).
|
|
||||||
Find(&dependents).Error
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(500, gin.H{"error": err.Error()})
|
c.JSON(500, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
@@ -84,7 +78,9 @@ func GetDependents(c *gin.Context) {
|
|||||||
c.JSON(200, models.DependentsResponse{
|
c.JSON(200, models.DependentsResponse{
|
||||||
AddonID: addonID,
|
AddonID: addonID,
|
||||||
Dependents: dependents,
|
Dependents: dependents,
|
||||||
Total: len(dependents),
|
Total: total,
|
||||||
|
Limit: limit,
|
||||||
|
Offset: offset,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,15 +95,9 @@ func GetDependencies(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
limit := parseLimit(c.Query("limit"))
|
limit := parseLimit(c.Query("limit"))
|
||||||
|
offset := parseOffset(c.Query("offset"))
|
||||||
|
|
||||||
dependencies := []models.AddonSearchResult{}
|
dependencies, total, err := queryRelatedAddons(addonID, "ad.dependency_id", "ad.addon_id", limit, offset)
|
||||||
err := initializers.DB.Model(&models.Addon{}).
|
|
||||||
Select("addons.id, addons.name, addons.type, addons.summary, addons.preview, addons.subscriber_count, addons.current_version_number, addons.author").
|
|
||||||
Joins("JOIN addon_dependencies ad ON ad.dependency_id = addons.id").
|
|
||||||
Where("ad.addon_id = ?", addonID).
|
|
||||||
Order("addons.subscriber_count DESC").
|
|
||||||
Limit(limit).
|
|
||||||
Find(&dependencies).Error
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(500, gin.H{"error": err.Error()})
|
c.JSON(500, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
@@ -116,10 +106,46 @@ func GetDependencies(c *gin.Context) {
|
|||||||
c.JSON(200, models.DependenciesResponse{
|
c.JSON(200, models.DependenciesResponse{
|
||||||
AddonID: addonID,
|
AddonID: addonID,
|
||||||
Dependencies: dependencies,
|
Dependencies: dependencies,
|
||||||
Total: len(dependencies),
|
Total: total,
|
||||||
|
Limit: limit,
|
||||||
|
Offset: offset,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// queryRelatedAddons returns one page of addons linked to addonID through the
|
||||||
|
// addon_dependencies edge table, plus the total number of matches.
|
||||||
|
//
|
||||||
|
// joinCol is the edge column joined to addons.id; filterCol is the edge column
|
||||||
|
// matched against addonID. Both are caller-supplied constants, never user input.
|
||||||
|
//
|
||||||
|
// The addons.id tiebreaker in the ORDER BY is required: subscriber_count alone
|
||||||
|
// is not a unique ordering, so without it paging could repeat or skip rows.
|
||||||
|
func queryRelatedAddons(addonID, joinCol, filterCol string, limit, offset int) ([]models.AddonSearchResult, int, error) {
|
||||||
|
base := func() *gorm.DB {
|
||||||
|
return initializers.DB.Model(&models.Addon{}).
|
||||||
|
Joins("JOIN addon_dependencies ad ON "+joinCol+" = addons.id").
|
||||||
|
Where(filterCol+" = ?", addonID)
|
||||||
|
}
|
||||||
|
|
||||||
|
var total int64
|
||||||
|
if err := base().Count(&total).Error; err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
results := []models.AddonSearchResult{}
|
||||||
|
err := base().
|
||||||
|
Select("addons.id, addons.name, addons.type, addons.summary, addons.preview, addons.subscriber_count, addons.current_version_number, addons.author").
|
||||||
|
Order("addons.subscriber_count DESC, addons.id ASC").
|
||||||
|
Limit(limit).
|
||||||
|
Offset(offset).
|
||||||
|
Find(&results).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return results, int(total), nil
|
||||||
|
}
|
||||||
|
|
||||||
func parseLimit(raw string) int {
|
func parseLimit(raw string) int {
|
||||||
limit := 100
|
limit := 100
|
||||||
if raw != "" {
|
if raw != "" {
|
||||||
@@ -132,3 +158,14 @@ func parseLimit(raw string) int {
|
|||||||
}
|
}
|
||||||
return limit
|
return limit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseOffset(raw string) int {
|
||||||
|
if raw == "" {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
val, err := strconv.Atoi(raw)
|
||||||
|
if err != nil || val < 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|||||||
+8
-2
@@ -66,18 +66,24 @@ type DependencyReport struct {
|
|||||||
Dependencies []DependencyReportItem `json:"dependencies"`
|
Dependencies []DependencyReportItem `json:"dependencies"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DependentsResponse lists the addons that depend on a given addon
|
// DependentsResponse lists one page of the addons that depend on a given addon.
|
||||||
|
// Total is the full number of matches, not the length of this page.
|
||||||
type DependentsResponse struct {
|
type DependentsResponse struct {
|
||||||
AddonID string `json:"addonId"`
|
AddonID string `json:"addonId"`
|
||||||
Dependents []AddonSearchResult `json:"dependents"`
|
Dependents []AddonSearchResult `json:"dependents"`
|
||||||
Total int `json:"total"`
|
Total int `json:"total"`
|
||||||
|
Limit int `json:"limit"`
|
||||||
|
Offset int `json:"offset"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DependenciesResponse lists the addons a given addon depends on
|
// DependenciesResponse lists one page of the addons a given addon depends on.
|
||||||
|
// Total is the full number of matches, not the length of this page.
|
||||||
type DependenciesResponse struct {
|
type DependenciesResponse struct {
|
||||||
AddonID string `json:"addonId"`
|
AddonID string `json:"addonId"`
|
||||||
Dependencies []AddonSearchResult `json:"dependencies"`
|
Dependencies []AddonSearchResult `json:"dependencies"`
|
||||||
Total int `json:"total"`
|
Total int `json:"total"`
|
||||||
|
Limit int `json:"limit"`
|
||||||
|
Offset int `json:"offset"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchResponse contains the search results
|
// SearchResponse contains the search results
|
||||||
|
|||||||
Reference in New Issue
Block a user