feat: add a new endpoint - GET /api/v1/versions/:code/servers

This commit is contained in:
Dawid Wysokiński 2022-08-23 07:16:49 +02:00
parent 9367b1f7e7
commit 0ad7b9a4af
Signed by: Kichiyaki
GPG Key ID: B5445E357FB8B892
7 changed files with 673 additions and 0 deletions

View File

@ -33,6 +33,7 @@ func NewBuilding(b domain.Building) Building {
BuildTimeFactor: b.BuildTimeFactor,
}
}
func (b Building) ToDomain() domain.Building {
return domain.Building{
MaxLevel: b.MaxLevel,
@ -91,6 +92,7 @@ func NewBuildingInfo(info domain.BuildingInfo) BuildingInfo {
Wall: NewBuilding(info.Wall),
}
}
func (b BuildingInfo) ToDomain() domain.BuildingInfo {
return domain.BuildingInfo{
Main: b.Main.ToDomain(),

View File

@ -0,0 +1,77 @@
package model
import "gitea.dwysokinski.me/twhelp/core/internal/domain"
type Building struct {
MaxLevel int8 `json:"maxLevel"`
MinLevel int8 `json:"minLevel"`
Wood int32 `json:"wood"`
Stone int32 `json:"stone"`
Iron int32 `json:"iron"`
Pop int16 `json:"pop"`
WoodFactor float64 `json:"woodFactor"`
StoneFactor float64 `json:"stoneFactor"`
IronFactor float64 `json:"ironFactor"`
PopFactor float64 `json:"popFactor"`
BuildTime float64 `json:"buildTime"`
BuildTimeFactor float64 `json:"buildTimeFactor"`
} // @name Building
func NewBuilding(b domain.Building) Building {
return Building{
MaxLevel: b.MaxLevel,
MinLevel: b.MinLevel,
Wood: b.Wood,
Stone: b.Stone,
Iron: b.Iron,
Pop: b.Pop,
WoodFactor: b.WoodFactor,
StoneFactor: b.StoneFactor,
IronFactor: b.IronFactor,
PopFactor: b.PopFactor,
BuildTime: b.BuildTime,
BuildTimeFactor: b.BuildTimeFactor,
}
}
type BuildingInfo struct {
Main Building `json:"main"`
Barracks Building `json:"barracks"`
Stable Building `json:"stable"`
Garage Building `json:"garage"`
Watchtower Building `json:"watchtower"`
Snob Building `json:"snob"`
Smith Building `json:"smith"`
Place Building `json:"place"`
Statue Building `json:"statue"`
Market Building `json:"market"`
Wood Building `json:"wood"`
Stone Building `json:"stone"`
Iron Building `json:"iron"`
Farm Building `json:"farm"`
Storage Building `json:"storage"`
Hide Building `json:"hide"`
Wall Building `json:"wall"`
} // @name BuildingInfo
func NewBuildingInfo(info domain.BuildingInfo) BuildingInfo {
return BuildingInfo{
Main: NewBuilding(info.Main),
Barracks: NewBuilding(info.Barracks),
Stable: NewBuilding(info.Stable),
Garage: NewBuilding(info.Garage),
Watchtower: NewBuilding(info.Watchtower),
Snob: NewBuilding(info.Snob),
Smith: NewBuilding(info.Smith),
Place: NewBuilding(info.Place),
Statue: NewBuilding(info.Statue),
Market: NewBuilding(info.Market),
Wood: NewBuilding(info.Wood),
Stone: NewBuilding(info.Stone),
Iron: NewBuilding(info.Iron),
Farm: NewBuilding(info.Farm),
Storage: NewBuilding(info.Storage),
Hide: NewBuilding(info.Hide),
Wall: NewBuilding(info.Wall),
}
}

View File

@ -0,0 +1,127 @@
package model_test
import (
"testing"
"github.com/stretchr/testify/assert"
"gitea.dwysokinski.me/twhelp/core/internal/rest/internal/model"
"gitea.dwysokinski.me/twhelp/core/internal/domain"
)
func TestNewBuildingInfo(t *testing.T) {
t.Parallel()
info := domain.BuildingInfo{
Main: domain.Building{
MaxLevel: 124,
Wood: 12224,
},
Barracks: domain.Building{
MinLevel: 22,
Stone: 12341,
},
Stable: domain.Building{
Wood: 22241,
Pop: 111,
},
Garage: domain.Building{
Stone: 11121,
WoodFactor: 0.99,
},
Watchtower: domain.Building{
Iron: 123412,
StoneFactor: 0.878,
},
Snob: domain.Building{
Pop: 789,
PopFactor: 0.11,
},
Smith: domain.Building{
BuildTime: 23.49999,
BuildTimeFactor: 0.999,
},
Place: domain.Building{
MaxLevel: 112,
},
Statue: domain.Building{
MinLevel: 123,
},
Market: domain.Building{
Pop: 1234,
},
Wood: domain.Building{
WoodFactor: 0.998,
},
Stone: domain.Building{
StoneFactor: 0.777,
},
Iron: domain.Building{
IronFactor: 0.5689,
},
Farm: domain.Building{
PopFactor: 0.9,
},
Storage: domain.Building{
MaxLevel: 31,
},
Hide: domain.Building{
MinLevel: 1,
},
Wall: domain.Building{
MaxLevel: 20,
MinLevel: 0,
Wood: 1234,
Stone: 1231,
Iron: 3214,
Pop: 1,
WoodFactor: 0.999,
StoneFactor: 0.998,
IronFactor: 0.977,
PopFactor: 2,
BuildTime: 30.5,
BuildTimeFactor: 0.5,
},
}
assertBuildingInfo(t, info, model.NewBuildingInfo(info))
}
func assertBuildingInfo(tb testing.TB, dbi domain.BuildingInfo, rbi model.BuildingInfo) {
tb.Helper()
assertBuilding(tb, dbi.Main, rbi.Main)
assertBuilding(tb, dbi.Barracks, rbi.Barracks)
assertBuilding(tb, dbi.Stable, rbi.Stable)
assertBuilding(tb, dbi.Garage, rbi.Garage)
assertBuilding(tb, dbi.Watchtower, rbi.Watchtower)
assertBuilding(tb, dbi.Snob, rbi.Snob)
assertBuilding(tb, dbi.Smith, rbi.Smith)
assertBuilding(tb, dbi.Place, rbi.Place)
assertBuilding(tb, dbi.Statue, rbi.Statue)
assertBuilding(tb, dbi.Market, rbi.Market)
assertBuilding(tb, dbi.Wood, rbi.Wood)
assertBuilding(tb, dbi.Stone, rbi.Stone)
assertBuilding(tb, dbi.Iron, rbi.Iron)
assertBuilding(tb, dbi.Farm, rbi.Farm)
assertBuilding(tb, dbi.Storage, rbi.Storage)
assertBuilding(tb, dbi.Hide, rbi.Hide)
assertBuilding(tb, dbi.Wall, rbi.Wall)
}
func assertBuilding(tb testing.TB, db domain.Building, rb model.Building) {
tb.Helper()
assert.Equal(tb, db.MaxLevel, rb.MaxLevel)
assert.Equal(tb, db.MinLevel, rb.MinLevel)
assert.Equal(tb, db.Wood, rb.Wood)
assert.Equal(tb, db.Stone, rb.Stone)
assert.Equal(tb, db.Iron, rb.Iron)
assert.Equal(tb, db.Pop, rb.Pop)
assert.Equal(tb, db.WoodFactor, rb.WoodFactor)
assert.Equal(tb, db.StoneFactor, rb.StoneFactor)
assert.Equal(tb, db.IronFactor, rb.IronFactor)
assert.Equal(tb, db.PopFactor, rb.PopFactor)
assert.Equal(tb, db.BuildTime, rb.BuildTime)
assert.Equal(tb, db.BuildTimeFactor, rb.BuildTimeFactor)
}

View File

@ -0,0 +1,41 @@
package model
import (
"time"
"gitea.dwysokinski.me/twhelp/core/internal/domain"
)
type Server struct {
Key string `json:"key"`
URL string `json:"url"`
Open bool `json:"open"`
NumPlayers int64 `json:"numPlayers"`
NumTribes int64 `json:"numTribes"`
NumVillages int64 `json:"numVillages"`
Config ServerConfig `json:"config"`
BuildingInfo BuildingInfo `json:"buildingInfo"`
UnitInfo UnitInfo `json:"unitInfo"`
CreatedAt time.Time `json:"createdAt"`
PlayerDataUpdatedAt time.Time `json:"playerDataUpdatedAt"`
TribeDataUpdatedAt time.Time `json:"tribeDataUpdatedAt"`
VillageDataUpdatedAt time.Time `json:"villageDataUpdatedAt"`
} // @name Server
func NewServer(s domain.Server) Server {
return Server{
Key: s.Key,
URL: s.URL,
Open: s.Open,
NumPlayers: s.NumPlayers,
NumTribes: s.NumTribes,
NumVillages: s.NumVillages,
Config: NewServerConfig(s.Config),
BuildingInfo: NewBuildingInfo(s.BuildingInfo),
UnitInfo: NewUnitInfo(s.UnitInfo),
CreatedAt: s.CreatedAt,
PlayerDataUpdatedAt: s.PlayerDataUpdatedAt,
TribeDataUpdatedAt: s.TribeDataUpdatedAt,
VillageDataUpdatedAt: s.TribeDataUpdatedAt,
}
}

View File

@ -0,0 +1,335 @@
package model
import "gitea.dwysokinski.me/twhelp/core/internal/domain"
type ServerConfigBuild struct {
Destroy int8 `json:"destroy"`
} // @name ServerConfigBuild
func NewServerConfigBuild(b domain.ServerConfigBuild) ServerConfigBuild {
return ServerConfigBuild{
Destroy: b.Destroy,
}
}
type ServerConfigMisc struct {
KillRanking int8 `json:"killRanking"`
Tutorial int8 `json:"tutorial"`
TradeCancelTime int16 `json:"tradeCancelTime"`
} // @name ServerConfigMisc
func NewServerConfigMisc(m domain.ServerConfigMisc) ServerConfigMisc {
return ServerConfigMisc{
KillRanking: m.KillRanking,
Tutorial: m.Tutorial,
TradeCancelTime: m.TradeCancelTime,
}
}
type ServerConfigCommands struct {
MillisArrival int16 `json:"millisArrival"`
CommandCancelTime int16 `json:"commandCancelTime"`
} // @name ServerConfigCommands
func NewServerConfigCommands(c domain.ServerConfigCommands) ServerConfigCommands {
return ServerConfigCommands{
MillisArrival: c.MillisArrival,
CommandCancelTime: c.CommandCancelTime,
}
}
type ServerConfigNewbie struct {
Days int16 `json:"days"`
RatioDays int16 `json:"ratioDays"`
Ratio int16 `json:"ratio"`
RemoveNewbieVillages int8 `json:"removeNewbieVillages"`
} // @name ServerConfigNewbie
func NewServerConfigNewbie(n domain.ServerConfigNewbie) ServerConfigNewbie {
return ServerConfigNewbie{
Days: n.Days,
RatioDays: n.RatioDays,
Ratio: n.Ratio,
RemoveNewbieVillages: n.RemoveNewbieVillages,
}
}
type ServerConfigGame struct {
BuildtimeFormula int8 `json:"buildtimeFormula"`
Knight int8 `json:"knight"`
KnightNewItems int8 `json:"knightNewItems"`
Archer int8 `json:"archer"`
Tech int8 `json:"tech"`
FarmLimit int32 `json:"farmLimit"`
Church int8 `json:"church"`
Watchtower int8 `json:"watchtower"`
Stronghold int8 `json:"stronghold"`
FakeLimit float64 `json:"fakeLimit"`
BarbarianRise float64 `json:"barbarianRise"`
BarbarianShrink int8 `json:"barbarianShrink"`
BarbarianMaxPoints int32 `json:"barbarianMaxPoints"`
Hauls int8 `json:"hauls"`
HaulsBase int32 `json:"haulsBase"`
HaulsMax int32 `json:"haulsMax"`
BaseProduction int32 `json:"baseProduction"`
Event int16 `json:"event"`
SuppressEvents int8 `json:"suppressEvents"`
} // @name ServerConfigGame
func NewServerConfigGame(g domain.ServerConfigGame) ServerConfigGame {
return ServerConfigGame{
BuildtimeFormula: g.BuildtimeFormula,
Knight: g.Knight,
KnightNewItems: g.KnightNewItems,
Archer: g.Archer,
Tech: g.Tech,
FarmLimit: g.FarmLimit,
Church: g.Church,
Watchtower: g.Watchtower,
Stronghold: g.Stronghold,
FakeLimit: g.FakeLimit,
BarbarianRise: g.BarbarianRise,
BarbarianShrink: g.BarbarianShrink,
BarbarianMaxPoints: g.BarbarianMaxPoints,
Hauls: g.Hauls,
HaulsBase: g.HaulsBase,
HaulsMax: g.HaulsMax,
BaseProduction: g.BaseProduction,
Event: g.Event,
SuppressEvents: g.SuppressEvents,
}
}
type ServerConfigBuildings struct {
CustomMain int8 `json:"customMain"`
CustomFarm int8 `json:"customFarm"`
CustomStorage int8 `json:"customStorage"`
CustomPlace int8 `json:"customPlace"`
CustomBarracks int8 `json:"customBarracks"`
CustomChurch int8 `json:"customChurch"`
CustomSmith int8 `json:"customSmith"`
CustomWood int8 `json:"customWood"`
CustomStone int8 `json:"customStone"`
CustomIron int8 `json:"customIron"`
CustomMarket int8 `json:"customMarket"`
CustomStable int8 `json:"customStable"`
CustomWall int8 `json:"customWall"`
CustomGarage int8 `json:"customGarage"`
CustomHide int8 `json:"customHide"`
CustomSnob int8 `json:"customSnob"`
CustomStatue int8 `json:"customStatue"`
CustomWatchtower int8 `json:"customWatchtower"`
} // @name ServerConfigBuildings
func NewServerConfigBuildings(b domain.ServerConfigBuildings) ServerConfigBuildings {
return ServerConfigBuildings{
CustomMain: b.CustomMain,
CustomFarm: b.CustomFarm,
CustomStorage: b.CustomStorage,
CustomPlace: b.CustomPlace,
CustomBarracks: b.CustomBarracks,
CustomChurch: b.CustomChurch,
CustomSmith: b.CustomSmith,
CustomWood: b.CustomWood,
CustomStone: b.CustomStone,
CustomIron: b.CustomIron,
CustomMarket: b.CustomMarket,
CustomStable: b.CustomStable,
CustomWall: b.CustomWall,
CustomGarage: b.CustomGarage,
CustomHide: b.CustomHide,
CustomSnob: b.CustomSnob,
CustomStatue: b.CustomStatue,
CustomWatchtower: b.CustomWatchtower,
}
}
type ServerConfigSnob struct {
Gold int8 `json:"gold"`
CheapRebuild int8 `json:"cheapRebuild"`
Rise int8 `json:"rise"`
MaxDist int16 `json:"maxDist"`
Factor float64 `json:"factor"`
CoinWood int32 `json:"coinWood"`
CoinStone int32 `json:"coinStone"`
CoinIron int32 `json:"coinIron"`
NoBarbConquer int8 `json:"noBarbConquer"`
} // @name ServerConfigSnob
func NewServerConfigSnob(s domain.ServerConfigSnob) ServerConfigSnob {
return ServerConfigSnob{
Gold: s.Gold,
CheapRebuild: s.CheapRebuild,
Rise: s.Rise,
MaxDist: s.MaxDist,
Factor: s.Factor,
CoinWood: s.CoinWood,
CoinStone: s.CoinStone,
CoinIron: s.CoinIron,
NoBarbConquer: s.NoBarbConquer,
}
}
type ServerConfigAlly struct {
NoHarm int8 `json:"noHarm"`
NoOtherSupport int8 `json:"noOtherSupport"`
NoOtherSupportType int8 `json:"noOtherSupportType"`
AllytimeSupport int32 `json:"allytimeSupport"`
NoLeave int8 `json:"noLeave"`
NoJoin int8 `json:"noJoin"`
Limit int16 `json:"limit"`
FixedAllies int8 `json:"fixedAllies"`
PointsMemberCount int32 `json:"pointsMemberCount"`
WarsMemberRequirement int16 `json:"warsMemberRequirement"`
WarsPointsRequirement int32 `json:"warsPointsRequirement"`
WarsAutoacceptDays int16 `json:"warsAutoacceptDays"`
Levels int8 `json:"levels"`
XpRequirements string `json:"xpRequirements"`
} // @name ServerConfigAlly
func NewServerConfigAlly(a domain.ServerConfigAlly) ServerConfigAlly {
return ServerConfigAlly{
NoHarm: a.NoHarm,
NoOtherSupport: a.NoOtherSupport,
NoOtherSupportType: a.NoOtherSupportType,
AllytimeSupport: a.AllytimeSupport,
NoLeave: a.NoLeave,
NoJoin: a.NoJoin,
Limit: a.Limit,
FixedAllies: a.FixedAllies,
PointsMemberCount: a.PointsMemberCount,
WarsMemberRequirement: a.WarsMemberRequirement,
WarsPointsRequirement: a.WarsPointsRequirement,
WarsAutoacceptDays: a.WarsAutoacceptDays,
Levels: a.Levels,
XpRequirements: a.XpRequirements,
}
}
type ServerConfigCoord struct {
MapSize int16 `json:"mapSize"`
Func int8 `json:"func"`
EmptyVillages int16 `json:"emptyVillages"`
BonusVillages int16 `json:"bonusVillages"`
BonusNew int16 `json:"bonusNew"`
Inner int16 `json:"inner"`
SelectStart int8 `json:"selectStart"`
VillageMoveWait int32 `json:"villageMoveWait"`
NobleRestart int8 `json:"nobleRestart"`
StartVillages int8 `json:"startVillages"`
} // @name ServerConfigCoord
func NewServerConfigCoord(c domain.ServerConfigCoord) ServerConfigCoord {
return ServerConfigCoord{
MapSize: c.MapSize,
Func: c.Func,
EmptyVillages: c.EmptyVillages,
BonusVillages: c.BonusVillages,
BonusNew: c.BonusNew,
Inner: c.Inner,
SelectStart: c.SelectStart,
VillageMoveWait: c.VillageMoveWait,
NobleRestart: c.NobleRestart,
StartVillages: c.StartVillages,
}
}
type ServerConfigSitter struct {
Allow int8 `json:"allow"`
} // @name ServerConfigSitter
func NewServerConfigSitter(s domain.ServerConfigSitter) ServerConfigSitter {
return ServerConfigSitter{
Allow: s.Allow,
}
}
type ServerConfigSleep struct {
Active int8 `json:"active"`
Delay int16 `json:"delay"`
Min int16 `json:"min"`
Max int16 `json:"max"`
MinAwake int16 `json:"minAwake"`
MaxAwake int16 `json:"maxAwake"`
WarnTime int16 `json:"warnTime"`
} // @name ServerConfigSleep
func NewServerConfigSleep(s domain.ServerConfigSleep) ServerConfigSleep {
return ServerConfigSleep{
Active: s.Active,
Delay: s.Delay,
Min: s.Min,
Max: s.Max,
MinAwake: s.MinAwake,
MaxAwake: s.MaxAwake,
WarnTime: s.WarnTime,
}
}
type ServerConfigNight struct {
Active int8 `json:"active"`
StartHour int8 `json:"startHour"`
EndHour int8 `json:"endHour"`
DefFactor float64 `json:"defFactor"`
Duration int8 `json:"duration"`
} // @name ServerConfigNight
func NewServerConfigNight(n domain.ServerConfigNight) ServerConfigNight {
return ServerConfigNight{
Active: n.Active,
StartHour: n.StartHour,
EndHour: n.EndHour,
DefFactor: n.DefFactor,
Duration: n.Duration,
}
}
type ServerConfigWin struct {
Check int16 `json:"check"`
} // @name ServerConfigWin
func NewServerConfigWin(w domain.ServerConfigWin) ServerConfigWin {
return ServerConfigWin{
Check: w.Check,
}
}
type ServerConfig struct {
Speed float64 `json:"speed"`
UnitSpeed float64 `json:"unitSpeed"`
Moral int16 `json:"moral"`
Build ServerConfigBuild `json:"build"`
Misc ServerConfigMisc `json:"misc"`
Commands ServerConfigCommands `json:"commands"`
Newbie ServerConfigNewbie `json:"newbie"`
Game ServerConfigGame `json:"game"`
Buildings ServerConfigBuildings `json:"buildings"`
Snob ServerConfigSnob `json:"snob"`
Ally ServerConfigAlly `json:"ally"`
Coord ServerConfigCoord `json:"coord"`
Sitter ServerConfigSitter `json:"sitter"`
Sleep ServerConfigSleep `json:"sleep"`
Night ServerConfigNight `json:"night"`
Win ServerConfigWin `json:"win"`
} // @name ServerConfig
func NewServerConfig(cfg domain.ServerConfig) ServerConfig {
return ServerConfig{
Speed: cfg.Speed,
UnitSpeed: cfg.UnitSpeed,
Moral: cfg.Moral,
Build: NewServerConfigBuild(cfg.Build),
Misc: NewServerConfigMisc(cfg.Misc),
Commands: NewServerConfigCommands(cfg.Commands),
Newbie: NewServerConfigNewbie(cfg.Newbie),
Game: NewServerConfigGame(cfg.Game),
Buildings: NewServerConfigBuildings(cfg.Buildings),
Snob: NewServerConfigSnob(cfg.Snob),
Ally: NewServerConfigAlly(cfg.Ally),
Coord: NewServerConfigCoord(cfg.Coord),
Sitter: NewServerConfigSitter(cfg.Sitter),
Sleep: NewServerConfigSleep(cfg.Sleep),
Night: NewServerConfigNight(cfg.Night),
Win: NewServerConfigWin(cfg.Win),
}
}

View File

@ -0,0 +1,61 @@
package model
import "gitea.dwysokinski.me/twhelp/core/internal/domain"
type Unit struct {
BuildTime float64 `json:"buildTime"`
Pop int16 `json:"pop"`
Speed float64 `json:"speed"`
Attack int16 `json:"attack"`
Defense int16 `json:"defense"`
DefenseCavalry int16 `json:"defenseCavalry"`
DefenseArcher int16 `json:"defenseArcher"`
Carry int16 `json:"carry"`
}
func NewUnit(u domain.Unit) Unit {
return Unit{
BuildTime: u.BuildTime,
Pop: u.Pop,
Speed: u.Speed,
Attack: u.Attack,
Defense: u.Defense,
DefenseCavalry: u.DefenseCavalry,
DefenseArcher: u.DefenseArcher,
Carry: u.Carry,
}
} // @name Unit
type UnitInfo struct {
Spear Unit `json:"spear"`
Sword Unit `json:"sword"`
Axe Unit `json:"axe"`
Archer Unit `json:"archer"`
Spy Unit `json:"spy"`
Light Unit `json:"light"`
Marcher Unit `json:"marcher"`
Heavy Unit `json:"heavy"`
Ram Unit `json:"ram"`
Catapult Unit `json:"catapult"`
Knight Unit `json:"knight"`
Snob Unit `json:"snob"`
Militia Unit `json:"militia"`
} // @name UnitInfo
func NewUnitInfo(info domain.UnitInfo) UnitInfo {
return UnitInfo{
Spear: NewUnit(info.Spear),
Sword: NewUnit(info.Sword),
Axe: NewUnit(info.Axe),
Archer: NewUnit(info.Archer),
Spy: NewUnit(info.Spy),
Light: NewUnit(info.Light),
Marcher: NewUnit(info.Marcher),
Heavy: NewUnit(info.Heavy),
Ram: NewUnit(info.Ram),
Catapult: NewUnit(info.Catapult),
Knight: NewUnit(info.Knight),
Snob: NewUnit(info.Snob),
Militia: NewUnit(info.Militia),
}
}

30
internal/rest/server.go Normal file
View File

@ -0,0 +1,30 @@
package rest
import (
"context"
"net/http"
"gitea.dwysokinski.me/twhelp/core/internal/domain"
"github.com/go-chi/chi/v5"
)
//counterfeiter:generate -o internal/mock/version_service.gen.go . ServerService
type ServerService interface {
List(ctx context.Context, params domain.ListServersParams) ([]domain.Server, int64, error)
}
type Server struct {
svc ServerService
}
func NewServer(svc ServerService) *Server {
return &Server{svc: svc}
}
func (s *Server) Register(r chi.Router) {
r.Get("/api/v1/versions/{versionCode}/servers", s.list)
}
func (s *Server) list(w http.ResponseWriter, r *http.Request) {
}