map, player, game, gamemode data now database driven

This commit is contained in:
Michael Simard
2021-10-31 00:01:27 -05:00
parent b0b0b7bc60
commit 64a66e28b8
22 changed files with 711 additions and 143 deletions

View File

@@ -0,0 +1,31 @@
//
// Configuration.swift
// App
//
// Created by Michael Simard on 10/29/21.
//
import Foundation
import Fluent
import Vapor
struct Configuration : Content {
var games:[GameConfig]
var gameModes:[GameModeConfig]
var gameModeGroups:[GameModeGroupConfig]
var players:[PlayerConfig]
var lossReasons:[LossReasonConfig]
init (games:[GameConfig], gameModes:[GameModeConfig], gameModeGroups:[GameModeGroupConfig], players:[PlayerConfig], lossReasons:[LossReasonConfig]){
self.games = games
self.gameModes = gameModes
self.gameModeGroups = gameModeGroups
self.players = players
self.lossReasons = lossReasons
}
}

View File

@@ -0,0 +1,22 @@
//
// GameConfig.swift
// App
//
// Created by Michael Simard on 10/29/21.
//
import Foundation
import Fluent
import Vapor
struct GameConfig: Content {
var gameId: String
var name: String
var maps: [MapConfig]
var enabled:Bool
}

View File

@@ -0,0 +1,18 @@
//
// GameModeConfig.swift
// App
//
// Created by Michael Simard on 10/29/21.
//
import Foundation
import Fluent
import Vapor
struct GameModeConfig:Content {
var gameModeId:Int
var name:String
var competitive:Bool
}

View File

@@ -0,0 +1,19 @@
//
// GameModeGroupConfig.swift
// App
//
// Created by Michael Simard on 10/29/21.
//
import Foundation
import Fluent
import Vapor
struct GameModeGroupConfig: Content {
var gameModeIds: String
var gameModeGroupId: String
var name: String
}

View File

@@ -0,0 +1,15 @@
//
// LossReasonsConfig.swift
// App
//
// Created by Michael Simard on 10/30/21.
//
import Foundation
import Fluent
import Vapor
struct LossReasonConfig: Content {
var reasonId: Int
var name: String
}

View File

@@ -0,0 +1,19 @@
//
// MapConfig.swift
// App
//
// Created by Michael Simard on 10/29/21.
//
import Foundation
import Fluent
import Vapor
struct MapConfig:Content, Hashable{
var mapId:Int
var name:String
var imageName:String
var gameModeGroupIds:[String]
}

View File

@@ -0,0 +1,15 @@
//
// PlayerConfig.swift
// App
//
// Created by Michael Simard on 10/30/21.
//
import Foundation
import Fluent
import Vapor
struct PlayerConfig: Content {
var playerId: Int
var name: String
}

View File

@@ -10,7 +10,7 @@ import Vapor
import Fluent
struct MapRecord: Content {
var map:Map
var map:MapConfig
var stats:Stats
var ratio:String
}

View File

@@ -7,7 +7,7 @@
import Foundation
struct Map: Hashable, Codable {
struct OldMap: Hashable, Codable {
var id: Int
var name:String
var imageName:String

View File

@@ -0,0 +1,66 @@
//
// AppDataController.swift
// App
//
// Created by Michael Simard on 10/29/21.
//
//
import Fluent
import Vapor
import Foundation
struct AppDataController: RouteCollection {
func boot(routes: RoutesBuilder) throws {
let matchRoute = routes.grouped("cod-tracker","api")
matchRoute.get("config", use: config)
}
func config(req:Request) -> EventLoopFuture<Configuration>{
let gameModeConfigs = GameMode.query(on: req.db).all().map { gameMode in
return gameMode.map { gm in
return gm.gameModeConfig
}
}
let gameModeGroupConfigs = GameModeGroup.query(on: req.db).all().map { gameModeGroup in
return gameModeGroup.map { gmg in
return gmg.gameModeGroupConfig
}
}
let games = Game.query(on: req.db).all()
let maps = Map.query(on: req.db).all()
let playerConfigs = Player.query(on: req.db).all().map { player in
return player.map { p in
return p.playerConfig
}
}
let lossReasonConfigs = LossReason.query(on: req.db).all().map { lossReason in
return lossReason.map { lr in
return lr.lossReasonConfig
}
}
return (gameModeConfigs.and(gameModeGroupConfigs).and(games).and(maps).and(playerConfigs).and(lossReasonConfigs)).map { arg -> (Configuration) in
let (((((( gameModeConfigs), gameModeGroupConfigs),games),maps),playerConfigs), lossReasonConfigs) = arg
var gameConfigs:[GameConfig] = []
gameConfigs = games.map({ game in
let mapConfigs = game.mapIds.compactMap { mapId in
return maps.first { m in
m.mapId == mapId
}?.mapConfig
}
return GameConfig(gameId: game.gameId, name: game.name, maps: mapConfigs, enabled: game.enabled)
})
return Configuration(games:gameConfigs, gameModes: gameModeConfigs, gameModeGroups: gameModeGroupConfigs, players: playerConfigs, lossReasons: lossReasonConfigs)
}
}
}

View File

@@ -0,0 +1,35 @@
//
// MapsController.swift
// App
//
// Created by Michael Simard on 10/29/21.
//
import Fluent
import Vapor
import Foundation
struct MapsController: RouteCollection {
func boot(routes: RoutesBuilder) throws {
let matchRoute = routes.grouped("cod-tracker","api", "maps")
matchRoute.get("all", use: maps)
matchRoute.get("game-modes", use: gameModes)
matchRoute.get("game-mode-groups", use: gameModeGroups)
}
func maps(req:Request) -> EventLoopFuture<[Map]>{
return Map.query(on: req.db).all()
}
func gameModes(req:Request) -> EventLoopFuture<[GameMode]>{
return GameMode.query(on: req.db).all()
}
func gameModeGroups(req:Request) -> EventLoopFuture<[GameModeGroup]>{
return GameModeGroup.query(on: req.db).all()
}
}

View File

@@ -28,7 +28,6 @@ struct StatsController: RouteCollection {
statsRoute.get("maps","game",":game","competitive",":competitive", "gamemode", ":gamemode",use: mapRecords)
statsRoute.get("dashboard", use: dashboard)
statsRoute.get("recalculate", use: recalc)
statsRoute.get("stats","q",":query", use: history)
}
@@ -236,11 +235,7 @@ struct StatsController: RouteCollection {
}
func getStatsWithMostRecentDailyRecord(sortedMatches:[Match], game:String? = nil) -> StatsWithMostRecentDailyRecord {
let startTime = Date()
//print ("MRR START \(Date().timeIntervalSince(startTime))")
let stats = getCountedMatches(matches: sortedMatches)
//print ("MRR STATS \(Date().timeIntervalSince(startTime))")
@@ -256,9 +251,7 @@ struct StatsController: RouteCollection {
func mostRecentDailyStats (matches:[Match], game:String? = nil) -> Stats{
let startTime = Date()
let daysPlayed = getDaysPlayed(sortedMatches: matches)
let lastDayPlayed = daysPlayed.last
@@ -359,10 +352,7 @@ struct StatsController: RouteCollection {
private func getDaysPlayed(sortedMatches:[Match]) -> [CODDate] {
let startTime = Date()
//print ("MDP Sort \(Date().timeIntervalSince(startTime))")
let dates = sortedMatches.suffix(30).map { (match) -> CODDate in
return CODDate(month: match.date.month, year: match.date.year, day: match.date.day, hour: match.date.hour, minute: match.date.minute)
}
@@ -618,11 +608,7 @@ struct StatsController: RouteCollection {
return self.getStatsForDay(year: days.first?.year ?? 0, month: days.first?.month ?? 0, day: days.first?.day ?? 0, req: req)
}
}
// func cachedStats(db: Database) -> EventLoopFuture<[String:Stats]> {
//
// }
func recalc(req:Request) -> EventLoopFuture<[String:Stats]> {
return forceCalculatedStats(db: req.db)
}
@@ -754,9 +740,12 @@ struct StatsController: RouteCollection {
let matches = Match.query(on: db).sort( \.$date).all()
return matches.and(dashboardStats).map { arg -> (OverallStats) in
let mapConfigs = mapConfigs(db: db)
return matches.and(dashboardStats).and(mapConfigs).map { arg -> (OverallStats) in
let (matches, dashboardStats) = arg
let ((matches, dashboardStats),mapConfigs) = arg
let queue = DispatchQueue(label: "com.sledsoft.cod-tracker.queue", attributes: .concurrent)
@@ -797,8 +786,8 @@ struct StatsController: RouteCollection {
(dashboardStats.dashboardItems +
[
DashboardItem(codTrackerId:"best_map_overall", title: "Best Map", content: MapData.allMaps[bestMap!]?.name ?? "error", title2: "Ratio", content2: "\(mapStats![bestMap!]!.winLossRatio) \(mapStats![bestMap!]!.record)", sortOrder: 12),
DashboardItem(codTrackerId:"worst_map_overall", title: "Worst Map", content: MapData.allMaps[worstMap!]?.name ?? "error", title2: "Ratio", content2: "\(mapStats![worstMap!]!.winLossRatio) \(mapStats![worstMap!]!.record)",sortOrder: 13),
DashboardItem(codTrackerId:"best_map_overall", title: "Best Map", content: mapConfigs.first{$0.mapId == bestMap}?.name ?? "error", title2: "Ratio", content2: "\(mapStats![bestMap!]!.winLossRatio) \(mapStats![bestMap!]!.record)", sortOrder: 12),
DashboardItem(codTrackerId:"worst_map_overall", title: "Worst Map", content: mapConfigs.first{$0.mapId == worstMap}?.name ?? "error", title2: "Ratio", content2: "\(mapStats![worstMap!]!.winLossRatio) \(mapStats![worstMap!]!.record)",sortOrder: 13),
]).sorted{
$0.sortOrder < $1.sortOrder
@@ -815,11 +804,25 @@ struct StatsController: RouteCollection {
}
func mapConfigs(db: Database) -> EventLoopFuture<[MapConfig]> {
return Map.query(on: db).all().map { map in
return map.map { m in
return m.mapConfig
}
}
}
func mapRecords(req: Request) throws -> EventLoopFuture<[MapRecord]> {
return Match.query(on: req.db).all().map { (matches) -> [MapRecord] in
let matches = Match.query(on: req.db).all()
let mapConfigs = mapConfigs(db: req.db)
return matches.and(mapConfigs).map { matches, mapConfigs in
let mapStats:[Int:Stats]
if let game = req.parameters.get("game", as: String.self),
@@ -833,10 +836,11 @@ struct StatsController: RouteCollection {
mapStats = self.getMapStats(matches: matches,game: "mw", competitive: true)
}
let sortedMaps = self.mapsSortedByBest(records: mapStats)
let sortedMaps = self.mapsSortedByBest(records: mapStats)
let records = sortedMaps.map { (mapId) -> MapRecord in
return MapRecord(map: MapData.allMaps[mapId]!, stats: mapStats[mapId]!, ratio:mapStats[mapId]!.winLossRatio)
return MapRecord(map: mapConfigs.first{$0.mapId == mapId}!, stats: mapStats[mapId]!, ratio:mapStats[mapId]!.winLossRatio)
}
var wins:Double = 0
@@ -849,7 +853,48 @@ struct StatsController: RouteCollection {
}
return records
}
//
// return Match.query(on: req.db).all().map { (matches) -> [MapRecord] in
//
//
//
// let mapStats:[Int:Stats]
//
// if let game = req.parameters.get("game", as: String.self),
// let competitive = req.parameters.get("competitive", as:Bool.self) {
//
// let gameMode = req.parameters.get("gamemode", as:Int.self) ?? -2
// mapStats = self.getMapStats(matches: matches,game: game, competitive: competitive, gameMode: gameMode)
//
// }
// else {
// mapStats = self.getMapStats(matches: matches,game: "mw", competitive: true)
// }
//
//
// let sortedMaps = self.mapsSortedByBest(records: mapStats)
//
// let records = sortedMaps.map { (mapId) -> MapRecord in
// return MapRecord(map: MapData.allMaps[mapId]!, stats: mapStats[mapId]!, ratio:mapStats[mapId]!.winLossRatio)
// }
//
// var wins:Double = 0
// var loss:Double = 0
//
// for record in records {
// //print("\(record.map.name) \(record.stats.record) \(record.ratio)")
// wins = wins + Double(record.stats.totalWins)
// loss = loss + Double(record.stats.totalLosses)
//
// }
// return records
// }
}
func mapsSortedByBest (records :[ Int:Stats] ) -> [ Int ] {

View File

@@ -7,119 +7,115 @@
import Foundation
class MapData {
static let allMaps:[Int:Map] = [
0: Map(id: 0, name: "Satellite", imageName: "bocw_satellite"),
1: Map(id: 1, name: "Armada", imageName: "bocw_armada"),
2: Map(id: 2, name: "Nuketown", imageName: "bocw_nuketown"),
3: Map(id: 3, name: "Cartel", imageName: "bocw_cartel"),
4: Map(id: 4, name: "Garrison", imageName: "bocw_garrison"),
5: Map(id: 5, name: "Miami", imageName: "bocw_miami"),
6: Map(id: 6, name: "Moscow", imageName: "bocw_moscow"),
7: Map(id: 7, name: "Crossroads", imageName: "bocw_crossroads"),
8: Map(id: 8, name: "Checkmate", imageName: "bocw_checkmate"),
9: Map(id: 9, name: "Arklov Peak", imageName: "mw_arklov"),
10: Map(id: 10, name: "Atlas Superstore", imageName: "mw_atlas"),
11: Map(id: 11, name: "Talsik Backlot", imageName: "mw_backlot"),
12: Map(id: 12, name: "Broadcast", imageName: "mw_broadcast"),
13: Map(id: 13, name: "Azhir Cave", imageName: "mw_caves"),
14: Map(id: 14, name: "Chesire Park", imageName: "mw_chesire"),
15: Map(id: 15, name: "Crash", imageName: "mw_crash"),
28: Map(id: 28, name: "Gun Runner", imageName: "mw_gunrunner"),
16: Map(id: 16, name: "Hackney Yard", imageName: "mw_hackney"),
17: Map(id: 17, name: "Suldal Harbor", imageName: "mw_harbor"),
18: Map(id: 18, name: "Hardhat", imageName: "mw_hardhat"),
19: Map(id: 19, name: "Hovec Sawmill", imageName: "mw_hovec"),
20: Map(id: 20, name: "Khandor Hideout", imageName: "mw_khandor"),
21: Map(id: 21, name: "Petrov Oil Rig", imageName: "mw_oil"),
22: Map(id: 22, name: "St. Petrograd", imageName: "mw_petrograd"),
23: Map(id: 23, name: "Rammaza", imageName: "mw_rammaza"),
24: Map(id: 24, name: "Scrapyard", imageName: "mw_scrapyard"),
25: Map(id: 25, name: "Shoot House", imageName: "mw_shoothouse"),
26: Map(id: 26, name: "Mialstor Tank Factory", imageName: "mw_tank"),
27: Map(id: 27, name: "Vacant", imageName: "mw_vacant"),
31: Map(id: 31, name: "The Pines", imageName: "bocw_pines"),
29: Map(id: 29, name: "Nuketown Holiday", imageName: "bocw_nuketown_holiday"),
30: Map(id: 30, name: "Raid", imageName: "bocw_raid"),
32: Map(id: 32, name: "Piccadilly", imageName: "mw_piccadilly"),
33: Map(id: 33, name: "Grazna Raid", imageName: "mw_grazna"),
34: Map(id: 34, name: "Express", imageName: "bocw_express"),
35: Map(id: 35, name: "Apocalypse", imageName: "bocw_apocalypse"),
36: Map(id: 36, name: "Killhouse", imageName: "mw_killhouse"),
37: Map(id: 37, name: "Al-Raab Airbase", imageName: "mw_airbase"),
38: Map(id: 38, name: "Yamantau", imageName: "bocw_yamantau"),
39: Map(id: 39, name: "Standoff", imageName: "bocw_standoff"),
40: Map(id: 40, name: "Rush", imageName: "bocw_rush"),
41: Map(id: 41, name: "Collateral", imageName: "bocw_collateral"),
42: Map(id: 42, name: "Diesel", imageName: "bocw_diesel"),
43: Map(id: 43, name: "Miami Strike", imageName: "bocw_miamistrike"),
44: Map(id: 44, name: "Amsterdam", imageName: "bocw_amsterdam"),
45: Map(id: 45, name: "Game Show", imageName: "bocw_gameshow"),
46: Map(id: 46, name: "ICBM", imageName: "bocw_icbm"),
47: Map(id: 47, name: "KGB", imageName: "bocw_kgb"),
48: Map(id: 48, name: "Mansion", imageName: "bocw_mansion"),
49: Map(id: 49, name: "U-Bahn", imageName: "bocw_ubahn"),
50: Map(id: 50, name: "Alpine", imageName: "bocw_alpine"),
51: Map(id: 51, name: "Duga", imageName: "bocw_duga"),
52: Map(id: 52, name: "Golova", imageName: "bocw_golova"),
53: Map(id: 53, name: "Ruka", imageName: "bocw_ruka"),
54: Map(id: 54, name: "Sanatorium", imageName: "bocw_sanatorium"),
55: Map(id: 55, name: "Hijacked", imageName: "bocw_hijacked"),
56: Map(id: 56, name: "Echelon", imageName: "bocw_echelon"),
57: Map(id: 57, name: "Slums", imageName: "bocw_slums"),
58: Map(id: 58, name: "Showroom", imageName: "bocw_showroom"),
59: Map(id: 59, name: "Drive-In", imageName: "bocw_drive-in"),
60: Map(id: 60, name: "Zoo", imageName: "bocw_zoo"),
//class MapData {
// static let allMaps:[Int:OldMap] = [
// 0: OldMap(id: 0, name: "Satellite", imageName: "bocw_satellite"),
// 1: OldMap(id: 1, name: "Armada", imageName: "bocw_armada"),
// 2: OldMap(id: 2, name: "Nuketown", imageName: "bocw_nuketown"),
// 3: OldMap(id: 3, name: "Cartel", imageName: "bocw_cartel"),
// 4: OldMap(id: 4, name: "Garrison", imageName: "bocw_garrison"),
// 5: OldMap(id: 5, name: "Miami", imageName: "bocw_miami"),
// 6: OldMap(id: 6, name: "Moscow", imageName: "bocw_moscow"),
// 7: OldMap(id: 7, name: "Crossroads", imageName: "bocw_crossroads"),
// 8: OldMap(id: 8, name: "Checkmate", imageName: "bocw_checkmate"),
// 9: OldMap(id: 9, name: "Arklov Peak", imageName: "mw_arklov"),
// 10: OldMap(id: 10, name: "Atlas Superstore", imageName: "mw_atlas"),
// 11: OldMap(id: 11, name: "Talsik Backlot", imageName: "mw_backlot"),
// 12: OldMap(id: 12, name: "Broadcast", imageName: "mw_broadcast"),
// 13: OldMap(id: 13, name: "Azhir Cave", imageName: "mw_caves"),
// 14: OldMap(id: 14, name: "Chesire Park", imageName: "mw_chesire"),
// 15: OldMap(id: 15, name: "Crash", imageName: "mw_crash"),
// 28: OldMap(id: 28, name: "Gun Runner", imageName: "mw_gunrunner"),
// 16: OldMap(id: 16, name: "Hackney Yard", imageName: "mw_hackney"),
// 17: OldMap(id: 17, name: "Suldal Harbor", imageName: "mw_harbor"),
// 18: OldMap(id: 18, name: "Hardhat", imageName: "mw_hardhat"),
// 19: OldMap(id: 19, name: "Hovec Sawmill", imageName: "mw_hovec"),
// 20: OldMap(id: 20, name: "Khandor Hideout", imageName: "mw_khandor"),
// 21: OldMap(id: 21, name: "Petrov Oil Rig", imageName: "mw_oil"),
// 22: OldMap(id: 22, name: "St. Petrograd", imageName: "mw_petrograd"),
// 23: OldMap(id: 23, name: "Rammaza", imageName: "mw_rammaza"),
// 24: OldMap(id: 24, name: "Scrapyard", imageName: "mw_scrapyard"),
// 25: OldMap(id: 25, name: "Shoot House", imageName: "mw_shoothouse"),
// 26: OldMap(id: 26, name: "Mialstor Tank Factory", imageName: "mw_tank"),
// 27: OldMap(id: 27, name: "Vacant", imageName: "mw_vacant"),
// 31: OldMap(id: 31, name: "The Pines", imageName: "bocw_pines"),
// 29: OldMap(id: 29, name: "Nuketown Holiday", imageName: "bocw_nuketown_holiday"),
// 30: OldMap(id: 30, name: "Raid", imageName: "bocw_raid"),
// 32: OldMap(id: 32, name: "Piccadilly", imageName: "mw_piccadilly"),
// 33: OldMap(id: 33, name: "Grazna Raid", imageName: "mw_grazna"),
// 34: OldMap(id: 34, name: "Express", imageName: "bocw_express"),
// 35: OldMap(id: 35, name: "Apocalypse", imageName: "bocw_apocalypse"),
// 36: OldMap(id: 36, name: "Killhouse", imageName: "mw_killhouse"),
// 37: OldMap(id: 37, name: "Al-Raab Airbase", imageName: "mw_airbase"),
// 38: OldMap(id: 38, name: "Yamantau", imageName: "bocw_yamantau"),
// 39: OldMap(id: 39, name: "Standoff", imageName: "bocw_standoff"),
// 40: OldMap(id: 40, name: "Rush", imageName: "bocw_rush"),
// 41: OldMap(id: 41, name: "Collateral", imageName: "bocw_collateral"),
// 42: OldMap(id: 42, name: "Diesel", imageName: "bocw_diesel"),
// 43: OldMap(id: 43, name: "Miami Strike", imageName: "bocw_miamistrike"),
//
// 44: OldMap(id: 44, name: "Amsterdam", imageName: "bocw_amsterdam"),
// 45: OldMap(id: 45, name: "Game Show", imageName: "bocw_gameshow"),
// 46: OldMap(id: 46, name: "ICBM", imageName: "bocw_icbm"),
// 47: OldMap(id: 47, name: "KGB", imageName: "bocw_kgb"),
// 48: OldMap(id: 48, name: "Mansion", imageName: "bocw_mansion"),
// 49: OldMap(id: 49, name: "U-Bahn", imageName: "bocw_ubahn"),
//
// 50: OldMap(id: 50, name: "Alpine", imageName: "bocw_alpine"),
// 51: OldMap(id: 51, name: "Duga", imageName: "bocw_duga"),
// 52: OldMap(id: 52, name: "Golova", imageName: "bocw_golova"),
// 53: OldMap(id: 53, name: "Ruka", imageName: "bocw_ruka"),
// 54: OldMap(id: 54, name: "Sanatorium", imageName: "bocw_sanatorium"),
// 55: OldMap(id: 55, name: "Hijacked", imageName: "bocw_hijacked"),
//
// 56: OldMap(id: 56, name: "Echelon", imageName: "bocw_echelon"),
// 57: OldMap(id: 57, name: "Slums", imageName: "bocw_slums"),
// 58: OldMap(id: 58, name: "Showroom", imageName: "bocw_showroom"),
// 59: OldMap(id: 59, name: "Drive-In", imageName: "bocw_drive-in"),
// 60: OldMap(id: 60, name: "Zoo", imageName: "bocw_zoo"),
61: Map(id: 61, name: "Champion Hill", imageName: "vg_championhill"),
62: Map(id: 62, name: "Hotel Royal", imageName: "vg_hotel"),
63: Map(id: 63, name: "Red Star", imageName: "vg_redstar"),
64: Map(id: 64, name: "Gavutu", imageName: "vg_gavutu"),
65: Map(id: 65, name: "Eagles Nest", imageName: "vg_eaglesnest"),
66: Map(id: 66, name: "Deprogram", imageName: "bocw_deprogram"),
67: Map(id: 67, name: "Amerika", imageName: "bocw_amerika"),
68: Map(id: 68, name: "Gluboko", imageName: "bocw_gluboko"),
69: Map(id: 69, name: "Nuketown Halloween", imageName: "bocw_nuketown_halloween"),
]
static let bocwMaps = {
return [1,3,8,7,4,2,29,31,5,6,30,0,34,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,66,67,68,69].compactMap {
return allMaps[$0];
}
.sorted { (m1, m2) -> Bool in
return m1.name < m2.name
}
}
static let mwMaps = {
return [9,10,11,12,13,14,15,28,16,17,18,19,20,21,22,23,24,25,26,27,32,33,36,37].compactMap {
return allMaps[$0]
}.sorted { (m1, m2) -> Bool in
return m1.name < m2.name
}
}
static let vgMaps = {
return [61,62,63,64,65].compactMap {
return allMaps[$0];
}.sorted { (m1, m2) -> Bool in
return m1.name < m2.name
}
}
}
// 61: OldMap(id: 61, name: "Champion Hill", imageName: "vg_championhill"),
// 62: OldMap(id: 62, name: "Hotel Royal", imageName: "vg_hotel"),
// 63: OldMap(id: 63, name: "Red Star", imageName: "vg_redstar"),
// 64: OldMap(id: 64, name: "Gavutu", imageName: "vg_gavutu"),
// 65: OldMap(id: 65, name: "Eagles Nest", imageName: "vg_eaglesnest"),
//
//
//
// 66: OldMap(id: 66, name: "Deprogram", imageName: "bocw_deprogram"),
// 67: OldMap(id: 67, name: "Amerika", imageName: "bocw_amerika"),
// 68: OldMap(id: 68, name: "Gluboko", imageName: "bocw_gluboko"),
//
// 69: OldMap(id: 69, name: "Nuketown Halloween", imageName: "bocw_nuketown_halloween"),
//
//
// ]
//
// static let bocwMaps = {
//
// return [1,3,8,7,4,2,29,31,5,6,30,0,34,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,66,67,68,69].compactMap {
// return allMaps[$0];
// }
// .sorted { (m1, m2) -> Bool in
// return m1.name < m2.name
// }
// }
// static let mwMaps = {
// return [9,10,11,12,13,14,15,28,16,17,18,19,20,21,22,23,24,25,26,27,32,33,36,37].compactMap {
// return allMaps[$0]
// }.sorted { (m1, m2) -> Bool in
// return m1.name < m2.name
// }
// }
//
// static let vgMaps = {
// return [61,62,63,64,65].compactMap {
// return allMaps[$0];
// }.sorted { (m1, m2) -> Bool in
// return m1.name < m2.name
// }
// }
//
//
//}

View File

@@ -0,0 +1,53 @@
//
// Game.swift
// App
//
// Created by Michael Simard on 10/29/21.
//
import Foundation
import Fluent
import Vapor
final class Game: Model, Content {
// Name of the table or collection.
static let schema = "game"
@ID(key: .id)
var id: UUID?
@Field(key: "game_id")
var gameId: String
@Field(key: "name")
var name: String
@Field(key: "maps")
var maps: String
@Field(key: "enabled")
var enabled: Bool
// Creates a new, empty .
init() { }
// Creates a new with all properties set.
init(id: UUID? = nil, gameId: String, name: String, maps:String, enabled:Bool) {
self.id = id
self.gameId = gameId
self.name = name
self.maps = maps
self.enabled = enabled
}
var mapIds:[Int] {
maps.components(separatedBy: ",").map{Int($0)!}
}
}

View File

@@ -0,0 +1,51 @@
//
// GameModes.swift
// App
//
// Created by Michael Simard on 10/29/21.
//
import Foundation
import Fluent
import Vapor
final class GameMode: Model, Content {
// Name of the table or collection.
static let schema = "game_mode"
@ID(key: .id)
var id: UUID?
@Field(key: "game_mode_id")
var gameModeId: Int
@Field(key: "name")
var name: String
@Field(key: "competitive")
var competitive: Bool
// Creates a new, empty .
init() { }
// Creates a new with all properties set.
init(id: UUID? = nil, gameModeId: Int, name: String, competitive:Bool) {
self.id = id
self.gameModeId = gameModeId
self.name = name
self.competitive = competitive
}
var gameModeConfig:GameModeConfig {
return GameModeConfig(gameModeId: gameModeId, name: name, competitive: competitive)
}
}

View File

@@ -0,0 +1,45 @@
//
// GameModeGroups.swift
// App
//
// Created by Michael Simard on 10/29/21.
//
import Fluent
import Vapor
final class GameModeGroup: Model, Content {
// Name of the table or collection.
static let schema = "game_mode_group"
@ID(key: .id)
var id: UUID?
@Field(key: "game_mode_ids")
var gameModeIds: String
@Field(key: "game_mode_group_id")
var gameModeGroupId: String
@Field(key: "name")
var name: String
// Creates a new, empty .
init() { }
// Creates a new with all properties set.
init(id: UUID? = nil, gameModeIds: String, name: String, gameModeGroupId:String) {
self.id = id
self.gameModeIds = gameModeIds
self.name = name
self.gameModeGroupId = gameModeGroupId
}
var gameModeGroupConfig: GameModeGroupConfig {
return GameModeGroupConfig(gameModeIds: gameModeIds, gameModeGroupId: gameModeGroupId, name: name)
}
}

View File

@@ -0,0 +1,43 @@
//
// LossReason.swift
// App
//
// Created by Michael Simard on 10/30/21.
//
import Fluent
import Vapor
import Fluent
import Vapor
final class LossReason: Model, Content {
// Name of the table or collection.
static let schema = "loss_reason"
@ID(key: .id)
var id: UUID?
@Field(key: "reason_id")
var reasonId: Int
@Field(key: "name")
var name: String
// Creates a new, empty .
init() { }
// Creates a new with all properties set.
init(id: UUID? = nil, lossReasonId: Int, name: String) {
self.id = id
self.reasonId = reasonId
self.name = name
}
var lossReasonConfig: LossReasonConfig {
return LossReasonConfig(reasonId: reasonId, name: name)
}
}

View File

@@ -0,0 +1,48 @@
//
// Map.swift
// App
//
// Created by Michael Simard on 10/29/21.
//
import Fluent
import Vapor
final class Map: Model, Content {
// Name of the table or collection.
static let schema = "map"
@ID(key: .id)
var id: UUID?
@Field(key: "name")
var name: String
@Field(key: "image_name")
var imageName: String
@Field(key: "game_mode_group_ids")
var gameModeGroupIds: String
@Field(key: "map_id")
var mapId: Int
// Creates a new, empty .
init() { }
// Creates a new with all properties set.
init(id: UUID? = nil, name: String, imageName: String, gameModeGroupIds: String, mapId:Int) {
self.id = id
self.name = name
self.imageName = imageName
self.gameModeGroupIds = gameModeGroupIds
self.mapId = mapId
}
var mapConfig:MapConfig {
return MapConfig(mapId: mapId, name: name, imageName: imageName, gameModeGroupIds: gameModeGroupIds.components(separatedBy: ","))
}
}

View File

@@ -47,11 +47,14 @@ final class Match: Model, Content {
var gameMode: Int
@Field(key: "lossReason")
var lossReason: Int
init() { }
init(id: UUID? = nil, map:String?, win:Bool, date:Date, roundsWon:Int?, roundsLost:Int?, codGame:String?, notes:String?, players:String?, sweaty:Bool?, finalKillRuinedPlayerId:Int?, numberOfFinalKillsRuined:Int?,competitive:Bool, gameMode:Int) {
init(id: UUID? = nil, map:String?, win:Bool, date:Date, roundsWon:Int?, roundsLost:Int?, codGame:String?, notes:String?, players:String?, sweaty:Bool?, finalKillRuinedPlayerId:Int?, numberOfFinalKillsRuined:Int?,competitive:Bool, gameMode:Int, lossReason:Int) {
self.id = id
self.map = map
self.win = win
@@ -66,7 +69,7 @@ final class Match: Model, Content {
self.numberOfFinalKillsRuined = numberOfFinalKillsRuined
self.competitive = competitive
self.gameMode = gameMode
self.lossReason = lossReason
}
func update( newMatch:Match) {
@@ -88,6 +91,7 @@ final class Match: Model, Content {
self.numberOfFinalKillsRuined = newMatch.numberOfFinalKillsRuined
self.competitive = newMatch.competitive
self.gameMode = newMatch.gameMode
self.lossReason = newMatch.lossReason
}

View File

@@ -0,0 +1,40 @@
//
// Player.swift
// App
//
// Created by Michael Simard on 10/30/21.
//
import Fluent
import Vapor
final class Player: Model, Content {
// Name of the table or collection.
static let schema = "player"
@ID(key: .id)
var id: UUID?
@Field(key: "player_id")
var playerId: Int
@Field(key: "name")
var name: String
// Creates a new, empty .
init() { }
// Creates a new with all properties set.
init(id: UUID? = nil, playerId: Int, name: String) {
self.id = id
self.playerId = playerId
self.name = name
}
var playerConfig: PlayerConfig {
return PlayerConfig(playerId: playerId, name: name)
}
}

View File

@@ -55,6 +55,7 @@ final class WinLossRecords: Model, Content {
self.wins = statistics.wins
self.losses = statistics.losses
self.codTrackerId = statistics.codTrackerId
}

View File

@@ -12,5 +12,7 @@ func routes(_ app: Application) throws {
try app.register(collection: StatsController())
try app.register(collection: MatchController())
try app.register(collection: MapsController())
try app.register(collection: AppDataController())
}