Browse Source

Add Side to match, add radiant & dire methods to match

Add get_JSON_any method to client
Move player and side definitions to own files
Change folder structure for better organization
Update README accordingly
Update .travis.yml to only check master branch

Basic definitions & sub-definitions pertaining to
classes are now in their own folders. Much cleaner
this way, and looks better in dota.cr requirements
calls.
master
Andrew Zah 2 years ago
parent
commit
0e21876703
Signed by: Andrew Zah <zah@andrewzah.com> GPG Key ID: 0AE942445EB70FAA

+ 3
- 0
.travis.yml View File

@@ -1,4 +1,7 @@
language: crystal
branches:
only:
- master
script:
- crystal deps
- crystal spec

+ 28
- 7
README.md View File

@@ -1,5 +1,4 @@

![Logo](https://sli.mg/IeIxRC.png)
![Logo](http://sli.mg/24VTkn.png)

[![Build Status](https://travis-ci.org/azah/dotacr.svg?branch=master)](https://travis-ci.org/azah/dotacr) [![docs](https://img.shields.io/badge/docs-latest-green.svg)](https://azah.github.io/dotacr/doc/master/)

@@ -39,7 +38,10 @@ Then use the client:

```crystal
api = Dota.api
```

## Supported API Methods
```crystal
api.hero(13) # => (Cached) A single hero - "Puck"
api.heroes # => (Cached) All heroes

@@ -86,7 +88,7 @@ api.cosmetic_rarities # => All cosmetic rarities
api.friends(76561198052976237) # => All friends of user
```

#### Custom Requests
## Custom Requests

For the unsupported endpoints, you can use `api.get`. For example, the following code is similar to `api.matches(789645621)` except it will return the raw JSON payload instead of an array of `Dota::Match`es.

@@ -101,6 +103,12 @@ api.get("GetMatchDetails", API::Match, "IDOTA2Match_570", {"match_id" => 7896456
* League => LeaguesList
* etc.

You can also get the response as `JSON::Any`, with `#get_JSON_any`:

```crystal
api.get_JSON_any("GetMatchDetails", "IDOTA2Match_570", {"match_id" => 789645621, "api_version" => "v1"})
```

## API Objects

### Hero
@@ -207,6 +215,8 @@ hero_id # Int32
`Dota::API::MatchesList` has one member: `matches: Array(Dota::API::Match)`.

```crystal
match.radiant # Dota::API::Match::Side
match.dire # Dota::API::Match::Side
match.id # Int64
match.radiant_win # Bool
match.duration # Int32, Length of the match, in seconds since the match began
@@ -265,14 +275,25 @@ player.item2_id # Int16
player.item3_id # Int16
player.item4_id # Int16
player.item5_id # Int16

# Dota::API::Match::Side
side.score # Int32
side.barracks_status # Dota::API::MatchStatus::Barracks
side.tower_status # Dota::API::MatchStatus::Towers
side.team_id # Int32 | Nil
side.team_name # String | Nil
side.team_logo # String | Nil
side.team_complete # Int32 | Nil
side.picks_bans # Array(Dota::API::Match::Draft) | Nil
side.players # Array(Dota::API::Match::Player) | Nil
```

#### Live Matches
`Dota::API::LiveMatchesList` has one member: `liveMatches: Array(Dota::API::Match)`.

```crystal
live_match.radiant # Dota::API::LiveMatch::Side, Info about the team on the Radiant side
live_match.dire # Dota::API::LiveMatch::Side, Info about the team on the Dire side
live_match.radiant # Dota::API::LiveMatch::Side
live_match.dire # Dota::API::LiveMatch::Side

live_match.id # Int64
live_match.lobby_id # Int64
@@ -306,7 +327,7 @@ sb.radiant # Dota::API::LiveMatch::Side
sb.dire # Dota::API::LiveMatch::Side
```

### Side (Currently only used by LiveMatch)
### Side
```crystal
side.score # Int32
side.tower_state # Enum, Dota::API::MatchStatus::Towers
@@ -352,7 +373,7 @@ lp.item5_id # Int16
`Dota::API::FriendsList` has one member: `friends: Array(Dota::API::Friend)`.

```crystal
friend.steamid # String
friend.steamid # String
friend.relationship # String
friend.friend_since # Int32
```

+ 1
- 1
shard.yml View File

@@ -1,5 +1,5 @@
name: dota
version: 0.0.1
version: 0.1.1

dependencies:
cossack:

+ 3
- 0
src/dota.cr View File

@@ -3,7 +3,10 @@ require "json"

require "./dota/utils/mapped"
require "./dota/api/status/*"
require "./dota/api/basic/*"
require "./dota/api/cosmetic/rarity"
require "./dota/api/match/*"
require "./dota/api/live_match/*"
require "./dota/*"
require "./dota/api/*"


src/dota/api/basic_match.cr → src/dota/api/basic/basic_match.cr View File


src/dota/api/basic_player.cr → src/dota/api/basic/basic_player.cr View File

@@ -3,7 +3,7 @@ module Dota
class BasicPlayer
JSON.mapping(
account_id: {type: Int64, nilable: true},
player_slot: Int8,
player_slot: Int16,
hero_id: Int8
)
end

+ 26
- 0
src/dota/api/client.cr View File

@@ -138,6 +138,32 @@ module Dota
raise ResponseException.new(result.error) if result.is_a?(ErrorResponse)
result
end

# For those who want a JSON::Any object to do their bidding with.
def get_JSON_any(method, interface, params)
do_request_JSON(method, interface, params)
end

private def do_request_JSON(method, interface = "IDOTA2Match_570", params = {} of String => String)
method_version = params.delete(:api_version) || configuration.api_version
url = "https://api.steampowered.com/#{interface}/#{method}/#{method_version}"
stringParams = {"key" => configuration.api_key.as(String)}
params.each { |k, v| stringParams[k] = "#{v}" }

@cossack = Cossack::Client.new(url)
response = @cossack.not_nil!.get("", stringParams)

if response.status != 200
case response.status
when 400...499
raise ClientErrorException.new("#{response.status}: #{response.body}")
when 500...599
raise ServerErrorException.new("#{response.status}: #{response.body}")
end
end

JSON.parse(response.body)
end
end
end
end

+ 15
- 68
src/dota/api/live_match.cr View File

@@ -23,8 +23,8 @@ module Dota
league_game_id: Int32,
stage_name: String,
league_tier: League::Tiers,
dire_team: {type: Team, nilable: true},
radiant_team: {type: Team, nilable: true},
dire_team: {type: SimpleTeam, nilable: true},
radiant_team: {type: SimpleTeam, nilable: true},
scoreboard: {type: Scoreboard, nilable: true}
)

@@ -36,6 +36,18 @@ module Dota
@scoreboard["roshan_respawn_timer"]
end

def radiant
if scoreboard = @scoreboard
return scoreboard.radiant
end
end

def dire
if scoreboard = @scoreboard
return scoreboard.dire
end
end

class SimplePlayer
include Dota::API::PlayerStatus
JSON.mapping(
@@ -46,7 +58,7 @@ module Dota
)
end

class Team
class SimpleTeam
include Dota::API::Converters

JSON.mapping(
@@ -65,71 +77,6 @@ module Dota
dire: Side
)
end

class Side
include Dota::API::MatchStatus

class Pick
JSON.mapping(hero_id: Int32)
end

class Ban
JSON.mapping(hero_id: Int32)
end

class Ability
JSON.mapping(
ability_id: Int32,
ability_level: Int8
)
end

JSON.mapping(
score: Int32,
tower_state: Towers,
barracks_state: Barracks,
picks: {type: Array(Pick), nilable: true},
bans: {type: Array(Ban), nilable: true},
players: Array(LivePlayer),
abilities: {type: Array(Ability), nilable: true}
)
end

class LivePlayer
JSON.mapping(
account_id: Int64,
player_slot: Int32,
hero_id: Int32,
level: Int8,
kills: Int16,
deaths: {key: "death", type: Int16},
assists: Int16,
last_hits: Int16,
denies: Int16,
gold: Int32,
gold_per_min: Int16,
xp_per_min: Int32,
ultimate_state: Int32,
ultimate_cooldown: Int32,
respawn_timer: Int32,
position_x: Float32,
position_y: Float32,
net_worth: Int32,
item0_id: {type: Int16, key: "item0"},
item1_id: {type: Int16, key: "item1"},
item2_id: {type: Int16, key: "item2"},
item3_id: {type: Int16, key: "item3"},
item4_id: {type: Int16, key: "item4"},
item5_id: {type: Int16, key: "item5"}
)

def items
[
item0_id, item1_id, item2_id,
item3_id, item4_id, item5_id,
].map { |id| Item.new(id.to_i32) }
end
end
end
end
end

+ 42
- 0
src/dota/api/live_match/live_player.cr View File

@@ -0,0 +1,42 @@
module Dota
module API
class LiveMatch
class LivePlayer
JSON.mapping(
account_id: Int64,
player_slot: Int32,
hero_id: Int32,
level: Int8,
kills: Int16,
deaths: {key: "death", type: Int16},
assists: Int16,
last_hits: Int16,
denies: Int16,
gold: Int32,
gold_per_min: Int16,
xp_per_min: Int32,
ultimate_state: Int32,
ultimate_cooldown: Int32,
respawn_timer: Int32,
position_x: Float32,
position_y: Float32,
net_worth: Int32,
item0_id: {type: Int16, key: "item0"},
item1_id: {type: Int16, key: "item1"},
item2_id: {type: Int16, key: "item2"},
item3_id: {type: Int16, key: "item3"},
item4_id: {type: Int16, key: "item4"},
item5_id: {type: Int16, key: "item5"},
name: {type: String, nilable: true}
)

def items
[
item0_id, item1_id, item2_id,
item3_id, item4_id, item5_id,
].map { |id| Item.new(id.to_i32) }
end
end
end
end
end

+ 34
- 0
src/dota/api/live_match/side.cr View File

@@ -0,0 +1,34 @@
module Dota
module API
class LiveMatch
class Side
include Dota::API::MatchStatus

class Pick
JSON.mapping(hero_id: Int32)
end

class Ban
JSON.mapping(hero_id: Int32)
end

class Ability
JSON.mapping(
ability_id: Int32,
ability_level: Int8
)
end

JSON.mapping(
score: Int32,
tower_state: Towers,
barracks_state: Barracks,
picks: {type: Array(Pick), nilable: true},
bans: {type: Array(Ban), nilable: true},
players: Array(LivePlayer),
abilities: {type: Array(Ability), nilable: true}
)
end
end
end
end

+ 14
- 24
src/dota/api/match.cr View File

@@ -46,6 +46,20 @@ module Dota
@match_id
end

def radiant
Side.new(:radiant, @radiant_score, @barracks_status_radiant,
@tower_status_radiant, @radiant_team_id, @radiant_name,
@radiant_logo, @radiant_team_complete, @radiant_captain,
@picks_bans, @players)
end

def dire
Side.new(:dire, @dire_score, @barracks_status_dire,
@tower_status_dire, @dire_team_id, @dire_name,
@dire_logo, @dire_team_complete, @dire_captain,
@picks_bans, @players)
end

class Draft
JSON.mapping(
is_pick: Bool,
@@ -54,30 +68,6 @@ module Dota
order: Int8
)
end

class Player < BasicPlayer
include Dota::API::PlayerStatus

JSON.mapping(
account_id: {type: Int64, nilable: true},
player_slot: Int8,
hero_id: Int8,
kills: Int16,
deaths: Int16,
assists: Int16,
leaver_status: Status,
last_hits: Int16,
denies: Int16,
gold_per_min: Int16,
xp_per_min: Int16,
item0_id: {type: Int16, key: "item_0"},
item1_id: {type: Int16, key: "item_1"},
item2_id: {type: Int16, key: "item_2"},
item3_id: {type: Int16, key: "item_3"},
item4_id: {type: Int16, key: "item_4"},
item5_id: {type: Int16, key: "item_5"}
)
end
end
end
end

+ 29
- 0
src/dota/api/match/player.cr View File

@@ -0,0 +1,29 @@
module Dota
module API
class Match
class Player < BasicPlayer
include Dota::API::PlayerStatus

JSON.mapping(
account_id: {type: Int64, nilable: true},
player_slot: Int16,
hero_id: Int8,
kills: Int16,
deaths: Int16,
assists: Int16,
leaver_status: Status,
last_hits: Int16,
denies: Int16,
gold_per_min: Int16,
xp_per_min: Int16,
item0_id: {type: Int16, key: "item_0"},
item1_id: {type: Int16, key: "item_1"},
item2_id: {type: Int16, key: "item_2"},
item3_id: {type: Int16, key: "item_3"},
item4_id: {type: Int16, key: "item_4"},
item5_id: {type: Int16, key: "item_5"}
)
end
end
end
end

+ 50
- 0
src/dota/api/match/side.cr View File

@@ -0,0 +1,50 @@
module Dota
module API
class Match
class Side
getter score, barracks_status, tower_status, id, name
getter logo, complete, captain, picks_bans, players

def initialize(
side : Symbol,
@score : Int32,
@barracks_status : Barracks,
@tower_status : Towers,
@team_id : Int32 | Nil = nil,
@team_name : String | Nil = nil,
@team_logo : String | Nil = nil,
@team_complete : Int32 | Nil = nil,
@team_captain : Int32 | Nil = nil,
@picks_bans : Array(Draft) | Nil = nil,
@players : Array(Player) | Nil = nil)
@players = sort_players(side)
@picks_bans = sort_picks_bans(side)
end

def sort_players(side : Symbol)
if players = @players
case side
when :radiant
players = players.reject { |player| (128..132).covers? player.player_slot }
when :dire
players = players.reject { |player| (0..4).covers? player.player_slot }
end
players
end
end

def sort_picks_bans(side : Symbol)
if picks_bans = @picks_bans
case side
when :radiant
picks_bans = picks_bans.reject { |pb| pb.team != Teams::Radiant }
when :dire
picks_bans = picks_bans.reject { |pb| pb.team != Teams::Dire }
end
picks_bans
end
end
end
end
end
end

+ 1
- 1
src/dota/version.cr View File

@@ -1,3 +1,3 @@
module Dota
VERSION = "0.0.1"
VERSION = "0.1.1"
end

Loading…
Cancel
Save