Support a creator

This commit is contained in:
Eccentric 2024-02-04 20:03:53 +00:00
parent 9e691170f6
commit c23d57a8c2
5 changed files with 59 additions and 13 deletions

View File

@ -141,6 +141,7 @@ func NewFortnitePersonWithId(id string, displayName string, everything bool) *p.
person.CommonCoreProfile.Attributes.AddAttribute(p.NewAttribute("mfa_enabled", true)).Save() person.CommonCoreProfile.Attributes.AddAttribute(p.NewAttribute("mfa_enabled", true)).Save()
person.CommonCoreProfile.Attributes.AddAttribute(p.NewAttribute("mtx_affiliate", "")).Save() person.CommonCoreProfile.Attributes.AddAttribute(p.NewAttribute("mtx_affiliate", "")).Save()
person.CommonCoreProfile.Attributes.AddAttribute(p.NewAttribute("mtx_affiliate_set_time", 0)).Save()
person.CommonCoreProfile.Attributes.AddAttribute(p.NewAttribute("mtx_purchase_history", aid.JSON{ person.CommonCoreProfile.Attributes.AddAttribute(p.NewAttribute("mtx_purchase_history", aid.JSON{
"refundsUsed": 0, "refundsUsed": 0,
"refundCredits": 3, "refundCredits": 3,

View File

@ -31,6 +31,7 @@ var (
"RefundMtxPurchase": clientRefundMtxPurchaseAction, "RefundMtxPurchase": clientRefundMtxPurchaseAction,
"GiftCatalogEntry": clientGiftCatalogEntryAction, "GiftCatalogEntry": clientGiftCatalogEntryAction,
"RemoveGiftBox": clientRemoveGiftBoxAction, "RemoveGiftBox": clientRemoveGiftBoxAction,
"SetAffiliateName": clientSetAffiliateNameAction,
} }
) )
@ -824,5 +825,33 @@ func clientRemoveGiftBoxAction(c *fiber.Ctx, person *p.Person, profile *p.Profil
profile.Gifts.DeleteGift(gift.ID) profile.Gifts.DeleteGift(gift.ID)
return nil
}
func clientSetAffiliateNameAction(c *fiber.Ctx, person *p.Person, profile *p.Profile, notifications *[]aid.JSON) error {
var body struct {
AffiliateName string `json:"affiliateName" binding:"required"`
}
if err := c.BodyParser(&body); err != nil {
return fmt.Errorf("invalid Body")
}
affiliate := person.CommonCoreProfile.Attributes.GetAttributeByKey("mtx_affiliate")
if affiliate == nil {
return c.Status(400).JSON(aid.ErrorBadRequest("Invalid affiliate attribute"))
}
affiliate.ValueJSON = aid.JSONStringify(body.AffiliateName)
affiliate.Save()
setTime := person.CommonCoreProfile.Attributes.GetAttributeByKey("mtx_affiliate_set_time")
if setTime == nil {
return c.Status(400).JSON(aid.ErrorBadRequest("Invalid affiliate set time attribute"))
}
setTime.ValueJSON = aid.JSONStringify(time.Now().Format("2006-01-02T15:04:05.999Z"))
setTime.Save()
return nil return nil
} }

View File

@ -2,6 +2,7 @@ package handlers
import ( import (
"github.com/ectrc/snow/aid" "github.com/ectrc/snow/aid"
p "github.com/ectrc/snow/person"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
) )
@ -10,41 +11,56 @@ func RedirectSocket(c *fiber.Ctx) error {
} }
func AnyNoContent(c *fiber.Ctx) error { func AnyNoContent(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusNoContent) return c.SendStatus(204)
} }
func PostGamePlatform(c *fiber.Ctx) error { func PostGamePlatform(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).SendString("true") return c.Status(200).SendString("true")
} }
func GetGameEnabledFeatures(c *fiber.Ctx) error { func GetGameEnabledFeatures(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).JSON([]string{}) return c.Status(200).JSON([]string{})
} }
func PostGameAccess(c *fiber.Ctx) error { func PostGameAccess(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).SendString("true") return c.Status(200).SendString("true")
} }
func GetFortniteReceipts(c *fiber.Ctx) error { func GetFortniteReceipts(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).JSON([]string{}) return c.Status(200).JSON([]string{})
} }
func GetMatchmakingSession(c *fiber.Ctx) error { func GetMatchmakingSession(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).Send([]byte{}) return c.Status(200).Send([]byte{})
} }
func GetFortniteVersion(c *fiber.Ctx) error { func GetFortniteVersion(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).JSON(aid.JSON{ return c.Status(200).JSON(aid.JSON{
"type": "NO_UPDATE", "type": "NO_UPDATE",
}) })
} }
func GetWaitingRoomStatus(c *fiber.Ctx) error { func GetWaitingRoomStatus(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusNoContent) return c.SendStatus(204)
}
func GetAffiliate(c *fiber.Ctx) error {
slugger := p.FindByDisplay(c.Params("slug"))
if slugger == nil {
return c.Status(400).JSON(aid.ErrorBadRequest("Invalid affiliate slug"))
}
return c.Status(200).JSON(aid.JSON{
"id": slugger.ID,
"displayName": slugger.DisplayName,
"slug": slugger.DisplayName,
"status": "ACTIVE",
"verified": false,
})
} }
func GetRegion(c *fiber.Ctx) error { func GetRegion(c *fiber.Ctx) error {
return c.Status(fiber.StatusOK).JSON(aid.JSON{ return c.Status(200).JSON(aid.JSON{
"continent": aid.JSON{ "continent": aid.JSON{
"code": "EU", "code": "EU",
}, },

View File

@ -75,12 +75,13 @@ func main() {
r.Use(aid.FiberLimiter()) r.Use(aid.FiberLimiter())
r.Use(aid.FiberCors()) r.Use(aid.FiberCors())
r.Post("/api/v1/assets/Fortnite/:versionId/:assetName", handlers.PostAssets)
r.Get("/region", handlers.GetRegion) r.Get("/region", handlers.GetRegion)
r.Put("/profile/play_region", handlers.AnyNoContent)
r.Get("/content/api/pages/fortnite-game", handlers.GetContentPages) r.Get("/content/api/pages/fortnite-game", handlers.GetContentPages)
r.Get("/waitingroom/api/waitingroom", handlers.GetWaitingRoomStatus) r.Get("/waitingroom/api/waitingroom", handlers.GetWaitingRoomStatus)
r.Get("/api/v1/search/:accountId", handlers.GetPersonSearch) r.Get("/api/v1/search/:accountId", handlers.GetPersonSearch)
r.Post("/api/v1/assets/Fortnite/:versionId/:assetName", handlers.PostAssets) r.Get("/affiliate/api/public/affiliates/slug/:slug", handlers.GetAffiliate)
r.Put("/profile/play_region", handlers.AnyNoContent)
r.Get("/", handlers.RedirectSocket) r.Get("/", handlers.RedirectSocket)
r.Get("/socket", handlers.MiddlewareWebsocket, websocket.New(handlers.WebsocketConnection)) r.Get("/socket", handlers.MiddlewareWebsocket, websocket.New(handlers.WebsocketConnection))

View File

@ -15,7 +15,6 @@ Performance first, universal Fortnite private server backend written in Go.
> The backend is very feature rich and is constantly being updated. Below are the features that are not yet implemented, but are coming soon. > The backend is very feature rich and is constantly being updated. Below are the features that are not yet implemented, but are coming soon.
- Amazon S3 integration to store the **Player Settings** externally. Using the bucket will allow for horizontal scaling which may be required for very large player counts.
- **Party System V2** Currently it relies on the automatic XMPP solution which is very hard to keep track of. - **Party System V2** Currently it relies on the automatic XMPP solution which is very hard to keep track of.
- Purchasing the **Battle Pass**. This will require the Battle Pass Storefront ID for every build. I am yet to think of a solution for this. - Purchasing the **Battle Pass**. This will require the Battle Pass Storefront ID for every build. I am yet to think of a solution for this.
- Seeded randomization for the **Item Shop** instead of a random number generator. This will ensure that even if the backend is restarted, the same random items will be in the shop during that day. - Seeded randomization for the **Item Shop** instead of a random number generator. This will ensure that even if the backend is restarted, the same random items will be in the shop during that day.
@ -27,7 +26,7 @@ Performance first, universal Fortnite private server backend written in Go.
> These are request made from Fortnite to the server to perform actions on the profile. > These are request made from Fortnite to the server to perform actions on the profile.
`QueryProfile`, `ClientQuestLogin`, `MarkItemSeen`, `SetItemFavoriteStatusBatch`, `EquipBattleRoyaleCustomization`, `SetBattleRoyaleBanner`, `SetCosmeticLockerSlot`, `SetCosmeticLockerBanner`, `SetCosmeticLockerName`, `CopyCosmeticLoadout`, `DeleteCosmeticLoadout`, `PurchaseCatalogEntry`, `GiftCatalogEntry`, `RemoveGiftBox` `QueryProfile`, `ClientQuestLogin`, `MarkItemSeen`, `SetItemFavoriteStatusBatch`, `EquipBattleRoyaleCustomization`, `SetBattleRoyaleBanner`, `SetCosmeticLockerSlot`, `SetCosmeticLockerBanner`, `SetCosmeticLockerName`, `CopyCosmeticLoadout`, `DeleteCosmeticLoadout`, `PurchaseCatalogEntry`, `GiftCatalogEntry`, `RemoveGiftBox`, `RefundMtxPurchase`, `SetAffiliateName`
## Support ## Support