@@ -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"))
|
||||
offset := parseOffset(c.Query("offset"))
|
||||
|
||||
dependents := []models.AddonSearchResult{}
|
||||
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
|
||||
dependents, total, err := queryRelatedAddons(addonID, "ad.addon_id", "ad.dependency_id", limit, offset)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
return
|
||||
@@ -84,7 +78,9 @@ func GetDependents(c *gin.Context) {
|
||||
c.JSON(200, models.DependentsResponse{
|
||||
AddonID: addonID,
|
||||
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"))
|
||||
offset := parseOffset(c.Query("offset"))
|
||||
|
||||
dependencies := []models.AddonSearchResult{}
|
||||
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
|
||||
dependencies, total, err := queryRelatedAddons(addonID, "ad.dependency_id", "ad.addon_id", limit, offset)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
return
|
||||
@@ -116,10 +106,46 @@ func GetDependencies(c *gin.Context) {
|
||||
c.JSON(200, models.DependenciesResponse{
|
||||
AddonID: addonID,
|
||||
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 {
|
||||
limit := 100
|
||||
if raw != "" {
|
||||
@@ -132,3 +158,14 @@ func parseLimit(raw string) int {
|
||||
}
|
||||
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"`
|
||||
}
|
||||
|
||||
// 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 {
|
||||
AddonID string `json:"addonId"`
|
||||
Dependents []AddonSearchResult `json:"dependents"`
|
||||
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 {
|
||||
AddonID string `json:"addonId"`
|
||||
Dependencies []AddonSearchResult `json:"dependencies"`
|
||||
Total int `json:"total"`
|
||||
Limit int `json:"limit"`
|
||||
Offset int `json:"offset"`
|
||||
}
|
||||
|
||||
// SearchResponse contains the search results
|
||||
|
||||
Reference in New Issue
Block a user