mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-08-23 19:46:28 -05:00
addDetailedTournament backend finished
This commit is contained in:
@@ -13,6 +13,10 @@ const {
|
||||
} = require("../utils/validators")
|
||||
|
||||
const typeDef = gql`
|
||||
extend type Query {
|
||||
plusDraftCups: DraftCupCollection!
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
addDetailedTournament(
|
||||
plus_server: PlusServer!
|
||||
@@ -22,6 +26,11 @@ const typeDef = gql`
|
||||
): Boolean!
|
||||
}
|
||||
|
||||
type DraftCupCollection {
|
||||
leaderboards: [Leaderboard!]!
|
||||
tournaments: [DetailedTournament!]!
|
||||
}
|
||||
|
||||
input DetailedTournamentInput {
|
||||
name: String!
|
||||
bracket_url: String!
|
||||
@@ -36,7 +45,7 @@ const typeDef = gql`
|
||||
bracket_url: String!
|
||||
date: String!
|
||||
top_3_team_names: [String!]!
|
||||
top_3_discord_ids: [[String!]!]!
|
||||
top_3_discord_users: [[User!]!]!
|
||||
participant_discord_ids: [String!]!
|
||||
type: EventType!
|
||||
}
|
||||
@@ -48,6 +57,7 @@ const typeDef = gql`
|
||||
}
|
||||
|
||||
type DetailedMatch {
|
||||
tournament_id: DetailedTournament!
|
||||
round_name: String!
|
||||
round_number: Int!
|
||||
map_details: [DetailedMap!]!
|
||||
@@ -63,7 +73,6 @@ const typeDef = gql`
|
||||
}
|
||||
|
||||
type DetailedMap {
|
||||
tournament_id: DetailedTournament!
|
||||
stage: String!
|
||||
mode: Mode!
|
||||
"Duration of the round in seconds"
|
||||
@@ -117,7 +126,7 @@ const typeDef = gql`
|
||||
}
|
||||
|
||||
type TournamentPlayer {
|
||||
discord_id: String!
|
||||
discord_user: User!
|
||||
"Number of first places"
|
||||
first: Int!
|
||||
"Number of second places"
|
||||
@@ -147,7 +156,120 @@ const typeDef = gql`
|
||||
}
|
||||
`
|
||||
|
||||
async function updateLeaderboard(top_3_discord_ids, type) {
|
||||
let leaderboard = await Leaderboard.findOne({ type })
|
||||
|
||||
if (!leaderboard) leaderboard = { players: [] }
|
||||
|
||||
const newPlayers = []
|
||||
|
||||
top_3_discord_ids.forEach((team, index) => {
|
||||
const placement = ["first", "second", "third"][index]
|
||||
team.forEach(discord_id => {
|
||||
const foundPlayer = leaderboard.players.find(
|
||||
player => discord_id === player.discord_id
|
||||
)
|
||||
if (foundPlayer) {
|
||||
foundPlayer[placement] = foundPlayer[placement] + 1
|
||||
} else {
|
||||
const newPlayer = { discord_id, first: 0, second: 0, third: 0 }
|
||||
newPlayer[placement] = newPlayer[placement] + 1
|
||||
newPlayers.push(newPlayer)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const newLeaderboard = {
|
||||
players: [...leaderboard.players, ...newPlayers],
|
||||
type,
|
||||
}
|
||||
newLeaderboard.players.sort(
|
||||
(a, b) =>
|
||||
b.first * 4 +
|
||||
b.second * 2 +
|
||||
b.third -
|
||||
(a.first * 4 + a.second * 2 + a.third)
|
||||
)
|
||||
|
||||
await Leaderboard.findOneAndUpdate({ type }, newLeaderboard, { upsert: true })
|
||||
}
|
||||
|
||||
async function generateStats(type) {
|
||||
const matches = await DetailedMatch.find({})
|
||||
const stats = {}
|
||||
matches.forEach(match => {
|
||||
match.map_details.forEach(map_detail => {
|
||||
const { duration, winners, losers } = map_detail
|
||||
;[winners, losers].forEach((teamInfo, index) => {
|
||||
teamInfo.players.forEach(player => {
|
||||
const {
|
||||
discord_id,
|
||||
weapon,
|
||||
kills,
|
||||
assists,
|
||||
deaths,
|
||||
specials,
|
||||
paint,
|
||||
} = player
|
||||
if (!stats[discord_id]) {
|
||||
stats[discord_id] = {}
|
||||
}
|
||||
;[weapon, "ALL"].forEach(weaponOrAll => {
|
||||
const weaponStats = stats[discord_id][weaponOrAll]
|
||||
? stats[discord_id][weaponOrAll]
|
||||
: {
|
||||
discord_id,
|
||||
weapon: weaponOrAll,
|
||||
kills: 0,
|
||||
assists: 0,
|
||||
deaths: 0,
|
||||
specials: 0,
|
||||
paint: 0,
|
||||
seconds_played: 0,
|
||||
games_played: 0,
|
||||
wins: 0,
|
||||
type,
|
||||
}
|
||||
weaponStats.kills = weaponStats.kills + kills
|
||||
weaponStats.assists = weaponStats.assists + assists
|
||||
weaponStats.deaths = weaponStats.deaths + deaths
|
||||
weaponStats.specials = weaponStats.specials + specials
|
||||
weaponStats.paint = weaponStats.paint + paint
|
||||
weaponStats.seconds_played = weaponStats.seconds_played + duration
|
||||
weaponStats.games_played = weaponStats.games_played + 1
|
||||
weaponStats.wins = weaponStats.wins + (index === 0 ? 1 : 0)
|
||||
|
||||
stats[discord_id][weaponOrAll] = weaponStats
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
const statsForDb = []
|
||||
Object.keys(stats).forEach(discord_id => {
|
||||
Object.keys(stats[discord_id]).forEach(weapon => {
|
||||
statsForDb.push(stats[discord_id][weapon])
|
||||
})
|
||||
})
|
||||
|
||||
PlayerStat.deleteMany({ type })
|
||||
await PlayerStat.insertMany(statsForDb)
|
||||
}
|
||||
|
||||
const resolvers = {
|
||||
Query: {
|
||||
plusDraftCups: async (root, args) => {
|
||||
const leaderboards = await Leaderboard.find()
|
||||
.or([{ type: "DRAFTONE" }, { type: "DRAFTTWO" }])
|
||||
.populate("players.discord_user")
|
||||
const tournaments = await DetailedTournament.find()
|
||||
.or([{ type: "DRAFTONE" }, { type: "DRAFTTWO" }])
|
||||
.populate("top_3_discord_users")
|
||||
|
||||
return { leaderboards, tournaments }
|
||||
},
|
||||
},
|
||||
Mutation: {
|
||||
addDetailedTournament: async (root, args) => {
|
||||
if (args.lanistaToken !== process.env.LANISTA_TOKEN) {
|
||||
@@ -166,20 +288,24 @@ const resolvers = {
|
||||
...maptInputProblems.flat(3),
|
||||
]
|
||||
|
||||
const eventType = args.plus_server === "TWO" ? "DRAFTTWO" : "DRAFTONE"
|
||||
if (problems.length > 0) {
|
||||
throw new UserInputError(problems.join(","))
|
||||
}
|
||||
|
||||
const eventType = args.plus_server === "TWO" ? "DRAFTTWO" : "DRAFTONE"
|
||||
const tournament = args.tournament
|
||||
tournament.type = eventType
|
||||
|
||||
//const savedTournament = await DetailedTournament.create(tournament)
|
||||
const savedTournament = await DetailedTournament.create(tournament)
|
||||
|
||||
//put matches in db
|
||||
//update leaderboard
|
||||
// stats?
|
||||
args.matches.forEach(match => {
|
||||
match.tournament_id = savedTournament._id
|
||||
match.type = eventType
|
||||
})
|
||||
|
||||
await DetailedMatch.insertMany(args.matches)
|
||||
|
||||
await updateLeaderboard(args.tournament.top_3_discord_ids, eventType)
|
||||
await generateStats(eventType)
|
||||
return true
|
||||
},
|
||||
},
|
||||
|
||||
@@ -20,10 +20,6 @@ const TeamInfo = {
|
||||
}
|
||||
|
||||
const Map = {
|
||||
tournament_id: {
|
||||
type: mongoose.Schema.Types.ObjectId,
|
||||
ref: "DetailedTournament",
|
||||
},
|
||||
stage: String,
|
||||
mode: String,
|
||||
duration: Number,
|
||||
@@ -32,9 +28,13 @@ const Map = {
|
||||
}
|
||||
|
||||
const detailedMatchSchema = new mongoose.Schema({
|
||||
tournament_id: {
|
||||
type: mongoose.Schema.Types.ObjectId,
|
||||
ref: "DetailedTournament",
|
||||
},
|
||||
round_number: Number,
|
||||
round_name: String,
|
||||
match_details: [Map],
|
||||
map_details: [Map],
|
||||
type: String,
|
||||
})
|
||||
|
||||
|
||||
@@ -10,4 +10,10 @@ const detailedTournamentSchema = new mongoose.Schema({
|
||||
type: String,
|
||||
})
|
||||
|
||||
detailedTournamentSchema.virtual("top_3_discord_users", {
|
||||
ref: "User",
|
||||
localField: "top_3_discord_ids",
|
||||
foreignField: "discord_id",
|
||||
})
|
||||
|
||||
module.exports = mongoose.model("DetailedTournament", detailedTournamentSchema)
|
||||
|
||||
@@ -12,4 +12,11 @@ const leaderboardSchema = new mongoose.Schema({
|
||||
type: String,
|
||||
})
|
||||
|
||||
leaderboardSchema.virtual("players.discord_user", {
|
||||
ref: "User",
|
||||
localField: "players.discord_id",
|
||||
foreignField: "discord_id",
|
||||
justOne: true,
|
||||
})
|
||||
|
||||
module.exports = mongoose.model("Leaderboard", leaderboardSchema)
|
||||
|
||||
Reference in New Issue
Block a user