Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ############################################################
- # #
- # Author: Kim "kimpact" Slavinjak #
- # E-Mail: kim@kimpact.info #
- # IRC: #kimpact @ quakenet #
- # Date: 08.06.2018 #
- # Version: 0.2 #
- # Info: This script uses the OpenDota API to call REST #
- # services and fetch json data to display over #
- # your Eggdrop Bot. This script will create a #
- # a file called recentmatch in your home #
- # directory to remember the last game you played. #
- # If you have questions, need help or have #
- # suggestions feel free to email me or find me #
- # on quakenet #
- # #
- # Installation: #
- # #
- # You need these lines in your eggdrop.conf #
- # -) set dotaapi(owner_steamid) "10694300" #
- # -> change the number to your steamid32 #
- # -) set dotaapi(post_recent_matches) 1 #
- # -> set this param to 1 and the bot will #
- # look if your steamid has played a new #
- # match every 40 minutes and post the stats #
- # in the channel below #
- # -) set dotaapi(channel) "#kimpact" #
- # -> change to the channel you want the bot #
- # to post stats in #
- # -) source scripts/dotaapi.tcl #
- # #
- # History: #
- # #
- # -) 08.06.18 - Init of the tcl script #
- # -) 09.06.18 - Added proc to periodically check #
- # recent matches of designated player #
- # in eggdrop conf defined player #
- # and write it publicly to channel #
- # -) 13.06.18 - Added call to return latest match #
- # stats per privmsg and alot of #
- # coloring to the dota stats #
- # #
- ############################################################
- #Required Packages
- ############################################################
- package require http
- package require rest
- package require tls
- package require json
- #Global variables
- ###########################################################
- global dotaapi
- #Inits for packages
- ############################################################
- http::register https 443 tls:socket
- #Bindings
- ############################################################
- bind msg - "wl" msg:restwl
- bind msg - "last_match" msg:last_match
- bind msg - "httpswl" msg:httpswl
- #Automation of procdedures
- ############################################################
- if { ![info exists recentmatch_running] && $dotaapi(post_recent_matches) } {
- timer 0 opendota:recent_match
- set recentmatch_running 1
- }
- #Procedures
- ############################################################
- #This procedure is needed to initialize TLS
- #If this isn't used, all https connections will be rejected
- #Therefore if you're just planning on calling http you
- #can delete it
- proc tls:socket args {
- set opts [lrange $args 0 end-2]
- set host [lindex $args end-1]
- set port [lindex $args end]
- ::tls::socket -servername $host {*}$opts $host $port
- ::tls::socket -ssl3 false -ssl2 false -tls1 true -servername $host {*}$opts $host $port
- }
- #Checks if the steamid32 is set and only numbers
- proc steam:checkid args {
- set steamid [lindex $args 0]
- if { $steamid != "" && [regexp {^[0-9]*$} $steamid] } {
- return 1
- } else {
- putlog "SteamId '$steamid' rejected"
- return 0
- }
- }
- #returns statistics of last match of received steamid
- #per privmasg
- proc msg:last_match { nick host hand args } {
- set steam_id [lindex $args 0]
- putlog "msg:last_match - received call from $nick for steam id $steam_id"
- if { [steam:checkid $steam_id] } {
- #get latest match into dict
- set d_result [opendota:get_last_match $steam_id]
- set lane [dict get $d_result "lane_role"]
- set lane [opendota:get_lane_string $lane]
- set player_slot [dict get $d_result "player_slot"]
- set player_slot [opendota:get_radiant_dire $player_slot]
- set radiant_win [dict get $d_result "radiant_win"]
- set game_mode [dict get $d_result "game_mode"]
- set lobby_type [dict get $d_result "lobby_type"]
- set game_type [opendota:game_type $game_mode $lobby_type]
- set kills [dict get $d_result "kills"]
- set deaths [dict get $d_result "deaths"]
- set assists [dict get $d_result "assists"]
- set xp_per_min [dict get $d_result "xp_per_min"]
- set gold_per_min [dict get $d_result "gold_per_min"]
- set hero_damage [dict get $d_result "hero_damage"]
- set tower_damage [dict get $d_result "tower_damage"]
- set hero_healing [dict get $d_result "hero_healing"]
- set last_hits [dict get $d_result "last_hits"]
- set leaver_status [dict get $d_result "leaver_status"]
- set party_size [dict get $d_result "party_size"]
- set hero_id [dict get $d_result "hero_id"]
- set hero_name [opendota:get_hero_name $hero_id]
- set lastmatchid [dict get $d_result "match_id"]
- #Output starts here
- #Finding out if we won
- if { ($player_slot == "radiant" && $radiant_win == true) || ($player_slot == "dire" && $radiant_win == false) } {
- puthelp "PRIVMSG $nick :\00303,01GG!\00309,01 Won the last \037$game_type\037 game as \037\00311,01$hero_name\037\00303,01 \00309,01in the \037$lane\037! \00303,01GG!"
- } else {
- puthelp "PRIVMSG $nick :\00304,01Unfortunately lost last \037$game_type\037 game as\00311,01 \037\00313,01$hero_name\037\00304,01 in the \037$lane\037.\00307,01.\00308,01."
- }
- puthelp "PRIVMSG $nick :\00300,01With a\00304,01 \00303,01K\00304,01D\00307,01A \00309,01$kills\00300,01|\00304,01$deaths\00300,01|\00307,01$assists\00309,01 \00300,01and\00309,01 \037\00313,01$last_hits\037 Last Hits\00300,01,"
- puthelp "PRIVMSG $nick :\037\00311,01$xp_per_min\037 XP/min\00309,01 \00300,01and\00309,01 \037\00308,01$gold_per_min\037 Gold/min\00300,01,"
- puthelp "PRIVMSG $nick :\00300,01they were able to inflict\00309,01 \037\00313,01$hero_damage\037\00305,01 \00313,01damage\00309,01 \00300,01to the enemy heroes and\00309,01 \037\00313,01$tower_damage\037\00306,01 \00313,01damage\00306,01 \00300,01to their towers.\00309,01"
- if { $hero_healing > 250 } {
- puthelp "PRIVMSG $nick :\00300,01All the while healing their friends and themselves for\00309,01 \037$hero_healing\037\00300,01."
- }
- if { $party_size > 1 && $lobby_type != "9" } {
- puthelp "PRIVMSG $nick :\00300,01By the by, they had the support of \037\00307,01[expr $party_size - 1] friend/s\037\00300,01 in form of a party."
- }
- if { $leaver_status > 0 } {
- puthelp "PRIVMSG $nick :\00314,01A\00315,01n\00300,01d \00314,01a\00315,01p\00300,01p\00315,01a\00314,01r\00315,01e\00300,01n\00315,01t\00314,01l\00315,01y\00300,01 \00314,01s\00315,01o\00300,01m\00315,01e\00314,01o\00315,01n\00300,01e \00315,01d\00314,01i\00315,01d\00300,01n\00315,01'\00314,01t\00300,01 \00315,01t\00300,01h\00315,01i\00314,01n\00315,01k\00300,01 i\00315,01t\00300,01 \00314,01w\00315,01a\00300,01s \00315,01w\00314,01o\00315,01r\00300,01t\00315,01h\00300,01 \00314,01t\00315,01h\00300,01e\00315,01i\00314,01r\00300,01 \00315,01t\00300,01i\00315,01m\00314,01e\00300,01 \00315,01t\00300,01o \00315,01s\00314,01t\00315,01a\00300,01y \00315,01u\00314,01n\00315,01t\00300,01i\00315,01l\00300,01 \00314,01t\00315,01h\00300,01e\00315,01 e\00314,01n\00315,01d\00300,01 o\00315,01f\00300,01 \00314,01t\00315,01h\00300,01e \00315,01m\00314,01a\00315,01t\00300,01c\00315,01h\00300,01."
- }
- puthelp "PRIVMSG $nick :\00304,01O\00307,01p\00308,01e\00303,01n\00309,01d\00311,01o\00312,01t\00306,01a\00304,01 L\00307,01i\00308,01n\00303,01k\00300,01: \00310,01https://www.opendota.com/matches/$lastmatchid"
- } else {
- puthelp "PRIVMSG $nick :Please call this function by messaging the bot with '/msg kimbot wl {yourSteamId}'"
- }
- }
- #get last played match from opendota and returns a dict with the stats
- proc opendota:get_last_match args {
- set steam_id [lindex $args 0]
- set url "https://api.opendota.com/api/players/$steam_id/recentMatches"
- set query "$steam_id"
- set res [rest::simple $url $query {
- method get
- content-type json
- }]
- #converting the received json to a dict
- set d_result [json::json2dict $res]
- set d_result [lindex $d_result 0]
- #since the opendota API returns the last 20 matches
- #we only get the latest match out of the list
- return $d_result
- }
- #periodically posts match data of the most recent match
- #in the home channel of the bot
- proc opendota:recent_match args {
- global dotaapi
- #check if set steamid is valid
- if { [steam:checkid $dotaapi(owner_steamid)] && $dotaapi(channel) != ""} {
- #open/create file and read the last known match (last known to the bot)
- set fs [open "~/recentmatch" a+]
- seek $fs 0
- gets $fs bots_lastmatchid
- close $fs
- putlog "opendota:recent_match - Last Match ID: '$bots_lastmatchid'"
- set d_result [opendota:get_last_match $dotaapi(owner_steamid)]
- set lastmatchid [dict get $d_result "match_id"]
- if { $lastmatchid != $bots_lastmatchid } {
- putlog "A new game was played by $dotaapi(owner_steamid) with the matchid $lastmatchid"
- #write the new matchid to the filesystem
- set fs [open "~/recentmatch" w]
- puts $fs $lastmatchid
- close $fs
- set lane [dict get $d_result "lane_role"]
- set lane [opendota:get_lane_string $lane]
- set player_slot [dict get $d_result "player_slot"]
- set player_slot [opendota:get_radiant_dire $player_slot]
- set radiant_win [dict get $d_result "radiant_win"]
- set game_mode [dict get $d_result "game_mode"]
- set lobby_type [dict get $d_result "lobby_type"]
- set game_type [opendota:game_type $game_mode $lobby_type]
- set kills [dict get $d_result "kills"]
- set deaths [dict get $d_result "deaths"]
- set assists [dict get $d_result "assists"]
- set xp_per_min [dict get $d_result "xp_per_min"]
- set gold_per_min [dict get $d_result "gold_per_min"]
- set hero_damage [dict get $d_result "hero_damage"]
- set tower_damage [dict get $d_result "tower_damage"]
- set hero_healing [dict get $d_result "hero_healing"]
- set last_hits [dict get $d_result "last_hits"]
- set leaver_status [dict get $d_result "leaver_status"]
- set party_size [dict get $d_result "party_size"]
- set hero_id [dict get $d_result "hero_id"]
- set hero_name [opendota:get_hero_name $hero_id]
- #Output starts here
- #Finding out if we won
- if { ($player_slot == "radiant" && $radiant_win == true) || ($player_slot == "dire" && $radiant_win == false) } {
- puthelp "PRIVMSG $dotaapi(channel) :\00303,01GG!\00309,01 Won the last \037$game_type\037 game as \037\00311,01$hero_name\037\00303,01 \00309,01in the \037$lane\037! \00303,01GG!"
- } else {
- puthelp "PRIVMSG $dotaapi(channel) :\00304,01Unfortunately lost last \037$game_type\037 game as\00311,01 \037\00313,01$hero_name\037\00304,01 in the \037$lane\037.\00307,01.\00308,01."
- }
- puthelp "PRIVMSG $dotaapi(channel) :\00300,01With a\00304,01 \00303,01K\00304,01D\00307,01A \00309,01$kills\00300,01|\00304,01$deaths\00300,01|\00307,01$assists\00309,01 \00300,01and\00309,01 \037\00313,01$last_hits\037 Last Hits\00300,01,"
- puthelp "PRIVMSG $dotaapi(channel) :\037\00311,01$xp_per_min\037 XP/min\00309,01 \00300,01and\00309,01 \037\00308,01$gold_per_min\037 Gold/min\00300,01,"
- puthelp "PRIVMSG $dotaapi(channel) :\00300,01they were able to inflict\00309,01 \037\00313,01$hero_damage\037\00305,01 \00313,01damage\00309,01 \00300,01to the enemy heroes and\00309,01 \037\00313,01$tower_damage\037\00306,01 \00313,01damage\00306,01 \00300,01to their towers.\00309,01"
- if { $hero_healing > 250 } {
- puthelp "PRIVMSG $dotaapi(channel) :\00300,01All the while healing their friends and themselves for\00309,01 \037$hero_healing\037\00300,01."
- }
- if { $party_size > 1 && $lobby_type != "9" } {
- puthelp "PRIVMSG $dotaapi(channel) :\00300,01By the by, they had the support of \037\00307,01[expr $party_size - 1] friend/s\037\00300,01 in form of a party."
- }
- if { $leaver_status > 0 } {
- puthelp "PRIVMSG $dotaapi(channel) :\00314,01A\00315,01n\00300,01d \00314,01a\00315,01p\00300,01p\00315,01a\00314,01r\00315,01e\00300,01n\00315,01t\00314,01l\00315,01y\00300,01 \00314,01s\00315,01o\00300,01m\00315,01e\00314,01o\00315,01n\00300,01e \00315,01d\00314,01i\00315,01d\00300,01n\00315,01'\00314,01t\00300,01 \00315,01t\00300,01h\00315,01i\00314,01n\00315,01k\00300,01 i\00315,01t\00300,01 \00314,01w\00315,01a\00300,01s \00315,01w\00314,01o\00315,01r\00300,01t\00315,01h\00300,01 \00314,01t\00315,01h\00300,01e\00315,01i\00314,01r\00300,01 \00315,01t\00300,01i\00315,01m\00314,01e\00300,01 \00315,01t\00300,01o \00315,01s\00314,01t\00315,01a\00300,01y \00315,01u\00314,01n\00315,01t\00300,01i\00315,01l\00300,01 \00314,01t\00315,01h\00300,01e\00315,01 e\00314,01n\00315,01d\00300,01 o\00315,01f\00300,01 \00314,01t\00315,01h\00300,01e \00315,01m\00314,01a\00315,01t\00300,01c\00315,01h\00300,01."
- }
- puthelp "PRIVMSG $dotaapi(channel) :\00304,01O\00307,01p\00308,01e\00303,01n\00309,01d\00311,01o\00312,01t\00306,01a\00304,01 L\00307,01i\00308,01n\00303,01k\00300,01: \00310,01https://www.opendota.com/matches/$lastmatchid"
- } else {
- putlog "openddota:recentmatch - No new match played since then"
- }
- #call the function in 40 minutes again
- timer 40 opendota:recent_match
- return 1
- } else {
- putlog "opendota:recent_match - The owner_steamid or channel is not set accordingly"
- putlog "opendota:recent_match - Please add 'set dotaapi(owner_steamid) {YourSteamId32}' and 'set dotaapi(channel) {#ChannelYourBotIsIn}' before dotaapi.tcl in the bots config"
- return 0
- }
- }
- #returns which type of game was played
- #TODO Add all game_modes
- proc opendota:game_type args {
- if { [llength $args] == 2 } {
- #game_mode: 22=normal, 23=turbo, 2=captains draft
- set game_mode [lindex $args 0]
- #lobby_type: 7=ranked, 0=unranked, 9=battlecup
- set lobby_type [lindex $args 1]
- switch $lobby_type {
- 0 {
- set result "unranked"
- }
- 7 {
- set result "ranked"
- }
- 9 {
- set result "battlecup"
- }
- default {
- set result "unknown lobby"
- }
- }
- switch $game_mode {
- 2 {
- set result "$result captains draft"
- }
- 22 {
- set result "$result normal"
- }
- 23 {
- set result "$result turbo"
- }
- default {
- set result "$result unknown game_mode"
- }
- }
- return $result
- } else {
- putlog "opendota:game_type - need 2 parameter: 1#: game_mode 2#: lobby_type"
- return 0
- }
- }
- #returns if player was radiant or dire
- proc opendota:get_radiant_dire args {
- set radiant_dire_id [lindex $args 0]
- #player_slot: 0-4=radiant, 128-132=dire
- if { $radiant_dire_id < 5 } {
- return "radiant"
- } else {
- return "dire"
- }
- }
- #returns name of the lane
- proc opendota:get_lane_string args {
- set lane [lindex $args 0]
- #lane: 1=safelane, 2=mid, 3=offlane
- switch $lane {
- 1 {
- set lane "safelane"
- }
- 2 {
- set lane "midlane"
- }
- 3 {
- set lane "offlane"
- }
- }
- return $lane
- }
- #get hero name through hero id
- #this procedure shouldnt actually be called everytime but rather
- #once per day or so and cached on the filesystem. Will do in a future update
- #TODO save hero infos locally and crosscheck for updates daily
- proc opendota:get_hero_name args {
- set hero_id [lindex $args 0]
- set url "https://api.opendota.com/api/heroes"
- set query ""
- set res [rest::simple $url $query {
- method get
- content-type json
- }]
- #converting the received json to a dict
- set d_result [json::json2dict $res]
- #set heroinfo [lindex $d_result $hero_id-2]
- foreach hero_info $d_result {
- if { [dict get $hero_info "id"] == $hero_id } {
- set hero_name [dict get $hero_info "localized_name"]
- break
- }
- }
- return $hero_name
- }
- #Bot replies with a msg with Wins and Losses of given steamid32
- proc msg:restwl { nick host hand args } {
- set steamid [lindex $args 0]
- putlog "W/L Call for SteamId $steamid by $nick received"
- if { [steam:checkid $steamid] } {
- set url "https://api.opendota.com/api/players/$steamid/wl"
- set query "$steamid"
- set res [rest::simple $url $query {
- method get
- content-type json
- }]
- #converting the received json to a dict
- set d_result [json::json2dict $res]
- #Only respond if the received json contained keys and values
- #and color the response flashy
- if { [dict size $d_result] > 0 } {
- puthelp "PRIVMSG $nick :\0033 Wins: \003 [dict get $d_result "win"]"
- puthelp "PRIVMSG $nick :\0034 Loses: \003 [dict get $d_result "lose"]"
- }
- } else {
- puthelp "PRIVMSG $nick :Please call this function by messaging the bot with '/msg kimbot wl {yourSteamId}'"
- }
- }
- proc msg:httpswl { nick host hand args } {
- global owner_steamid
- set token [::http::geturl "https://api.opendota.com/api/players/$steamid/wl" -type application/json]
- putlog "Token: $token"
- putlog "Data in Token: [::http::data $token]"
- puthelp "PRIVMSG $nick :[::http::data $token]"
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement