PSSplinterlands.psm1
function Get-slBalanceHistory { [CmdletBinding()] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] [Alias("PlayerName")] [string]$UserName, [Parameter()] [ValidateSet("DEC","SPS","Credits","Voucher","Merits")] [string]$TokenType = "DEC", [Parameter()] [int]$Limit = 5000, [Parameter()] [int]$Offset = 0 ) DynamicParam { $attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new() $attributes = [System.Management.Automation.ParameterAttribute]::new() $attributeCollection.Add($attributes) switch ($TokenType){ "DEC" { $ValidValues = [System.Management.Automation.ValidateSetAttribute]::new( "dec_reward", "season_rewards", "guild_contribution", "market_purchase", "market_rental", "rental_payment", "rental_refund", "rental_payment_fees", "market_fees", "quest_rewards", "burn_cards", "purchase_cl_presale_pack", "mystery_prize", "pack_purchase", "orb_purchase", "purchase_potion", "tournament_creation", "enter_tournament", "leave_tournament", "prize_tournament", "cancel_tournament", "token_transfer", "leaderboard_prizes", "token_award", "unpaid_prizes" ) break; } "SPS" { $ValidValues = [System.Management.Automation.ValidateSetAttribute]::new( "token_award", "stake_tokens", "claim_staking_rewards", "token_transfer", "purchase_cl_presale_pack", "tournament_payment", "enter_tournament", "leave_tournament", "prize_tournament", "cancel_tournament", "unpaid_prizes" ) break; } "Credits" { $ValidValues = [System.Management.Automation.ValidateSetAttribute]::new( "purchase_cl_presale_pack", "credits_purchase", "market_purchase", "market_rental", "purchase_booster_pack" ) break; } "Voucher" { $ValidValues = [System.Management.Automation.ValidateSetAttribute]::new( "purchase_cl_presale_pack_voucher", "voucher_drop", "token_transfer" ) break; } "Merits" { $ValidValues = [System.Management.Automation.ValidateSetAttribute]::new( "brawl_prize", "guild_gladius_purchase", "guild_bldstone_purchase", "guild_pwrstone_purchase" ) break; } } $attributeCollection.Add($ValidValues) $dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new( 'TransactionType', [string], $attributeCollection ) $paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() $paramDictionary.Add('TransactionType', $dynParam1) return $paramDictionary } Begin { $Uri = "https://api2.splinterlands.com/players/balance_history" } Process{ try{ $Body = @{ username = $UserName token_type = $TokenType.ToUpper() offset = $Offset limit = $Limit } if ($PSBoundParameters.ContainsKey("TransactionType")){ $Body["types"] = $PSBoundParameters["TransactionType"] } $transactions = Invoke-RestMethod -Uri $Uri -Body $Body | ForEach-Object {$_} foreach ($transaction in $transactions){ try { $transaction.created_date = [datetime]::Parse($transaction.created_date) } catch{ Write-Information "Unable to parse date for created_date property" } #try/catch $decimalProperties = "amount","balance_end","balance_start" foreach ($property in $decimalProperties){ $transaction.$property = [double]$transaction.$property } $transaction.psobject.typenames.insert(0,"splinterlands.balancehistory") $transaction } #foreach } catch{ $PSCmdlet.WriteError($_) } #try/catch } #Process } function Get-slBattleHistory { [CmdletBinding()] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] [Alias("UserName")] [string]$PlayerName ) try{ $Battles = Invoke-SplinterlandsAPI -Uri "https://game-api.splinterlands.io/battle/history?player=$PlayerName" foreach ($battle in $Battles.battles){ $battle.details = $battle.details | ConvertFrom-Json $Teams = @($battle.details.team1,$battle.details.team2) if ($PlayerName -eq $battle.player_1){ $Enemy = $battle.player_2 } else { $Enemy = $battle.player_1 } $battle | Add-Member -NotePropertyMembers @{ Player = $PlayerName Enemty = $Enemy PlayerTeam = $Teams | Where-Object player -eq $PlayerName EnemyTeam = $Teams | Where-Object player -eq $Enemy } $battle } } catch{ $PSCmdlet.WriteError($_) } } function Get-slCard { [CmdletBinding()] param( [int]$Id ) try{ $cards = Invoke-SplinterlandsAPI -Uri "https://api.splinterlands.io/cards/get_details" if ($cards){ foreach ($card in $cards){ $card | Add-Member -TypeName "splinterlands.card" Add-Member -InputObject $card -NotePropertyMembers @{ RarityName = Resolve-slRarity $card.Rarity EditionName = ($card.editions -split "," | Resolve-slEdition) } $card } } } catch{ $PSCmdlet.WriteError($_) } } function Get-slCardCollection { [CmdletBinding()] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] [Alias("UserName")] [string]$PlayerName ) try{ $Uri = "https://api.splinterlands.io/cards/collection/$PlayerName" $Collection = Invoke-SplinterlandsAPI -Uri $Uri $Collection.cards | ForEach-Object { Add-Member -InputObject $_ -TypeName "splinterlands.playercard" try{ $_.last_used_date = [datetime]::Parse($_.last_used_date) } catch{ Write-Information "Unable to parse date" } } $Collection.cards } catch{ $PSCmdlet.WriteError($_) } } function Get-slDailyDECBattleRewards { [CmdletBinding()] param( [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)] [Alias("PlayerName")] [string]$UserName, [int]$Limit = 5000 ) Process{ $balancehistoryParam = @{ UserName = $UserName TokenType = "DEC" Limit = $Limit TransactionType = "dec_reward" ErrorAction = "Stop" } try{ $decRewards = Get-slBalanceHistory @balancehistoryParam } catch{ Write-Error "Unable to get reward infor: $($_.Exception.Message)" -ErrorAction Stop } $groupbyDay = {$_.created_date.ToShortDateString()} $decRewardGroupByDay = $decRewards | Group-Object $groupbyDay foreach ($day in $decRewardGroupByDay){ [PSCustomObject]@{ Date = $day.Name BattleCount = $day.Count DecEarned = ($day.group | Measure-Object -property amount -Sum).sum } } } #Process } function Get-slDECRewardsSummary { [CmdletBinding()] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] [Alias("PlayerName")] $UserName ) Process { $allRewardList = [System.Collections.Generic.List[object]]::new() $rewardTypes = @("dec_reward","quest_rewards","season_rewards") foreach ($type in $rewardTypes){ try{ $firstandLastDate = $null $dateRange = $null $averageGamesperDay = $null $averageDailyEarned = $null $balancehistoryParam = @{ UserName = $UserName TokenType = "DEC" Limit = 5000 TransactionType = $type ErrorAction = "Stop" } $decRewards = Get-slBalanceHistory @balancehistoryParam $Stats = $decRewards | Measure-Object -Property amount -Sum -Average -Maximum -Minimum $groupbyDay = $decRewards | Group-Object -Property { $_.created_date.ToShortDateString() } $firstandLastDate = $decRewards | Sort-Object created_date | Select-Object -First 1 -Last 1 if (($firstandLastDate | Measure-Object).Count -eq 2){ $dateRange = New-TimeSpan -Start $firstandLastDate[0].created_date -End $firstandLastDate[1].created_date -ErrorAction SilentlyContinue $averageGamesperDay = [math]::round(($groupbyDay | Measure-Object -Property Count -Sum).Sum / $dateRange.Days) $averageDailyEarned = [math]::round(($groupbyDay.Group | Measure-Object -Property amount -Sum).Sum / $dateRange.Days) } $rewardTypeName = switch ($type){ "dec_reward" {"Battle"} "quest_rewards" {"Quest"} "season_rewards" {"Season"} } $rewardSumary = [PSCustomObject]@{ PSTypeName = "splinterlands.decrewardsummary" RewardType = $rewardTypeName RewardCount = ($decRewards | Measure-Object).Count AvgReward = [math]::Round($Stats.Average,2) TotalDays = $dateRange.Days AvgRewardsPerDay = $averageGamesperDay AvgDailyDEC = $averageDailyEarned Total = $Stats.Sum Stats = $Stats DateRange = $dateRange StartDate = ($firstandLastDate | Select-Object -First 1).created_date EndDate = ($firstandLastDate | Select-Object -Last 1).created_date RewardTransactions = $decRewards } $allRewardList.Add($rewardSumary) $rewardSumary } catch{ Write-Warning "Unable to calculate [$type] reward summary" } #try/catch } #foreach #summary $decRewards = $allRewardList.RewardTransactions $Stats = $decRewards | Measure-Object -Property amount -Sum -Average -Maximum -Minimum $groupbyDay = $decRewards | Group-Object -Property { $_.created_date.ToShortDateString() } $firstandLastDate = $decRewards | Sort-Object created_date | Select-Object -First 1 -Last 1 if (($firstandLastDate | Measure-Object).Count -eq 2){ $dateRange = New-TimeSpan -Start $firstandLastDate[0].created_date -End $firstandLastDate[1].created_date -ErrorAction SilentlyContinue $averageGamesperDay = [math]::round(($groupbyDay | Measure-Object -Property Count -Sum).Sum / $dateRange.Days) $averageDailyEarned = [math]::round(($groupbyDay.Group | Measure-Object -Property amount -Sum).Sum / $dateRange.Days) } [PSCustomObject]@{ PSTypeName = "splinterlands.decrewardsummary" RewardType = "All" RewardCount = ($decRewards | Measure-Object).Count AvgReward = [math]::Round($Stats.Average,2) TotalDays = $dateRange.Days AvgRewardsPerDay = $averageGamesperDay AvgDailyDEC = $averageDailyEarned Total = $Stats.Sum Stats = $Stats DateRange = $dateRange StartDate = ($firstandLastDate | Select-Object -First 1).created_date EndDate = ($firstandLastDate | Select-Object -Last 1).created_date RewardTransactions = $decRewards } } } function Get-slPlayerActiveRental { [CmdletBinding()] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] [string[]]$PlayerName, [Parameter()] [ValidateSet("renter","owner")] [string]$PlayerType = "renter" ) Process{ foreach ($player in $PlayerName){ $Rentals = Invoke-SplinterlandsAPI -Uri "https://api2.splinterlands.com/market/active_rentals?$PlayerType=$player" foreach ($rental in $Rentals){ try{ $rental.rental_date = [datetime]::Parse($rental.rental_date) $rental.next_rental_payment = [datetime]::Parse($rental.next_rental_payment) $rental.cancel_date = [datetime]::Parse($rental.cancel_date) } catch{ Write-Information "Unable to convert date properties to datetime type" } $rental | Add-Member -TypeName "splinterlands.playeractiverental" $rental | Add-Member -MemberType AliasProperty -Name DailyCost -Value buy_price $rental | Add-Member -MemberType NoteProperty -Name Cancelled -Value ([bool]$rental.cancel_tx) $rental } } #Foreach } #Process } function Get-slPlayerBattleSummary { [CmdletBinding()] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] [Alias("opponent_player")] [string]$PlayerName, [Parameter(ValueFromPipelineByPropertyName)] [Alias("inactive")] [string]$IgnoreColors ) Process{ $IgnoreColorsList = $IgnoreColors -split "," $allCards = Get-slCard $recentBattles = Get-slBattleHistory -PlayerName $PlayerName $battleCount = ($recentBattles | Measure-Object).Count $playerQuest = Get-slPlayersQuest -PlayerName $PlayerName $top3Summoners = $recentBattles.PlayerTeam | Where-Object color -notin $IgnoreColorsList | Select-Object -ExpandProperty summoner | Group-Object card_detail_id | Sort-Object Count -Descending | Select-Object -First 3 $summonerUsage = foreach ($summoner in $top3Summoners){ $summonerDetails = $allCards | Where-Object Id -eq $summoner.Name $sPercentage = [math]::round(($summoner.count / $battleCount * 100)) $summonerLevel = $summoner.group | Select-Object -First 1 -ExpandProperty level $summonerBattles = $recentBattles | Where-Object {$_.PlayerTeam.Summoner.card_detail_id -eq $summoner.name} $summonerBattleCount = ($summonerBattles | Measure-Object).Count $top6SummonerMonsters = $summonerBattles.PlayerTeam.monsters | Group-Object card_detail_id | Sort-Object Count -Descending | Select-Object -First 6 $TopSummonerMonsters = foreach ($monster in $top6SummonerMonsters){ $monsterDetails = $allCards | Where-Object Id -eq $monster.Name $monsterLevel = $monster.group | Select-Object -First 1 -ExpandProperty level $mPercentage = [math]::round(($monster.count / $summonerBattleCount * 100)) [PSCustomObject]@{ Monster = $monsterDetails Abilities = $monsterDetails.stats.abilities[0.. ($monsterLevel - 1)] MonsterLevel = $monsterLevel UsagePercentage = $mPercentage } } [PSCustomObject]@{ Summoner = $summonerDetails UsagePercentage = $sPercentage SummonerLevel = $summonerLevel TopSummonerMonsters = $TopSummonerMonsters } } $top6Monsters = $recentBattles.PlayerTeam.monsters | Group-Object card_detail_id | Sort-Object Count -Descending | Select-Object -First 6 $monsterUsage = foreach ($monster in $top6Monsters){ $monsterLevel = $monster.group | Select-Object -First 1 -ExpandProperty level $monsterDetails = $allCards | Where-Object Id -eq $Monster.Name $mPercentage = [math]::round(($monster.count / $battleCount * 100)) [PSCustomObject]@{ Monster = $monsterDetails MonsterLevel = $monsterLevel Abilities = $monsterDetails.stats.abilities[0.. ($monsterLevel - 1)] UsagePercentage = $mPercentage } } [PSCustomObject]@{ PSTypeName = "splinterlands.playerbattlesummary" PlayerName = $PlayerName CurrentQuest = $playerQuest TopSummoners = $summonerUsage TopMonsters = $monsterUsage } } #process } function Get-slPlayerOutstandingBattle { [CmdletBinding()] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] [Alias("UserName")] [string[]]$PlayerName ) Process{ foreach ($player in $PlayerName){ $Battle = Invoke-SplinterlandsAPI -uri " https://api2.splinterlands.com/players/outstanding_match?username=$PlayerName" #api returns a string 'null' if no battle if found if ($Battle -ne "null"){ $Battle | Add-Member -TypeName "splinterlands.outstandingbattle" $rulesetList = $Battle.ruleset -split "\|" | Where-Object {-not[string]::IsNullOrWhiteSpace($_)} $Battle | Add-Member -NotePropertyMembers @{ "RulesetList" = $rulesetList "RulesetListFriendly" = ($rulesetList | Resolve-slRuleset) } $dateProperties = "created_date","expiration_date","match_date","submit_expiration_date" foreach ($dateProperty in $dateProperties){ try{ $Battle.$dateProperty = [datetime]::Parse($battle.$dateProperty) } catch{ Write-Information "Unable to parse date property [$dateProperty]" } } #foreach date property $Battle } #if not null } #foreach player } #process } function Get-slPlayersQuest { [CmdletBinding()] param( [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)] [Alias("UserName")] [string[]]$PlayerName ) Process { foreach ($player in $PlayerName){ #foreach at the end is needed for some weird reason try{ $questInfo = Invoke-SplinterlandsAPI -Uri "https://api2.splinterlands.com/players/quests?username=$player" -ErrorAction Stop | ForEach-Object {$_} try{ $questInfo.created_date = [datetime]::Parse($questInfo.created_date) $questInfo.claim_date = [datetime]::Parse($questInfo.claim_date) } catch{ Write-Information "Unable to parse date" } $questInfo | Add-Member -TypeName "splinterlands.quest" $questInfo | Add-Member -MemberType NoteProperty -Name "QuestType" -Value (Resolve-slQuest $questInfo.Name) $questInfo | Add-Member -MemberType NoteProperty -Name "Completed" -Value ($questInfo.total_items -eq $questInfo.completed_items) $questInfo } catch{ $PSCmdlet.WriteError($_) } } } } function Invoke-SplinterlandsAPI { [CmdletBinding()] param( [Parameter(Mandatory)] $Uri ) try { Invoke-RestMethod -Uri $Uri } catch{ $PSCmdlet.WriteError($_) } } function Resolve-slEdition { [CmdletBinding()] param( [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)] [int]$Edition ) Process { switch ($Edition){ 0 {"Alpha"} 1 {"Beta"} 2 {"Promo"} 3 {"Reward"} 4 {"Untamed"} 5 {"Dice"} 6 {"Gladius"} default {"Unknown"} } } } function Resolve-slQuest { [CmdletBinding()] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] [string]$QuestName ) Process{ switch ($QuestName) { "Stir the Volcano" {"Fire"} "Lyanna's Call" {"Earth"} "Defend the Borders" {"Life"} "Rising Dead" {"Death"} "Pirate Attacks" {"Water"} "Stubborn Mercenaries" {"No Neutrals"} "High Priority Targets" {"Dragon"} "Stealth Mission" {"Sneak"} default {"Unknown"} } } } function Resolve-slRarity { [CmdletBinding()] param( [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)] [int]$Rarity ) Process { switch ($Rarity){ 1 {"Common"} 2 {"Rare"} 3 {"Epic"} 4 {"Summoner"} default {"Unknown"} } } } function Resolve-slRuleset { [CmdletBinding()] param( [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] [string[]]$RulesetName ) Process{ foreach ($ruleset in $RulesetName){ switch ($ruleset){ "Up Close & Personal" {"Melee Only"} "Spreading Fury" {"Fury Ability"} "Odd Ones Out" {"Odds Only"} default {$ruleset} } } } } Export-ModuleMember -function Get-slBalanceHistory, Get-slBattleHistory, Get-slCard, Get-slCardCollection, Get-slDailyDECBattleRewards, Get-slDECRewardsSummary, Get-slPlayerActiveRental, Get-slPlayerBattleSummary, Get-slPlayerOutstandingBattle, Get-slPlayersQuest |