271 lines
7.8 KiB
Lua
271 lines
7.8 KiB
Lua
--[[
|
|
Connection interface between PvPGN and GHost
|
|
https://github.com/OHSystem/ohsystem/issues/279
|
|
|
|
|
|
Copyright (C) 2014 HarpyWar (harpywar@gmail.com)
|
|
|
|
This file is a part of the PvPGN Project http://pvpgn.pro
|
|
Licensed under the same terms as Lua itself.
|
|
]]--
|
|
|
|
|
|
|
|
---------------------------------
|
|
--- GHOST -> PVPGN (CALLBACK) ---
|
|
---------------------------------
|
|
|
|
-- /ghost [cmd] [code] {args}
|
|
function command_ghost(account, text)
|
|
if not config.ghost then return 1 end
|
|
|
|
-- restrict commands for authorized bots only
|
|
if not gh_is_bot(account.name) then return 1 end
|
|
|
|
local args = split_command(text, 5)
|
|
local cmd = args[1]
|
|
local code = args[2]
|
|
|
|
if code ~= "ok" then
|
|
if code == "err" then
|
|
local err_message = args[3]
|
|
-- HINT: you can handle error here
|
|
end
|
|
return -1
|
|
end
|
|
|
|
-- /ghost init
|
|
if (cmd == "init") then
|
|
INFO("GHost bot is connected (" .. account.name .. ")")
|
|
|
|
-- /ghost gameresult [players] [ratings] [results]
|
|
elseif (cmd == "gameresult") then
|
|
gh_callback_gameresult(args[3], args[4], args[5])
|
|
|
|
-- /ghost host [code] [user] [gamename]
|
|
elseif (cmd == "host") then
|
|
args = split_command(text, 4) -- support game name with spaces
|
|
gh_callback_host(args[3], account.name, args[4])
|
|
-- /ghost chost [code] [user] [gamename]
|
|
elseif (cmd == "chost") then
|
|
args = split_command(text, 4) -- support game name with spaces
|
|
gh_callback_chost(args[3], account.name, args[4])
|
|
|
|
-- /ghost unhost [code] [user] [gamename]
|
|
elseif (cmd == "unhost") then
|
|
gh_callback_unhost(args[3], args[4])
|
|
|
|
-- /ghost ping [code] [user] [players] [pings]
|
|
elseif (cmd == "ping") then
|
|
gh_callback_ping(args[3], args[4], args[5])
|
|
|
|
-- /ghost swap [code] [user] [username1] [username2]
|
|
elseif (cmd == "swap") then
|
|
-- HINT: you can notify user about success usage
|
|
|
|
-- /ghost open [code] [user] [slot]
|
|
elseif (cmd == "open") or (cmd == "close") then
|
|
-- HINT: you can notify user about success usage
|
|
|
|
-- /ghost [cmd] [code] [user] [message]
|
|
elseif (cmd == "start") or (cmd == "abort")
|
|
or (cmd == "pub") or (cmd == "priv") then
|
|
-- HINT: you can notify user about success usage
|
|
end
|
|
|
|
-- FIXME: may be do not log commands from bot? (return -1)
|
|
return 0
|
|
end
|
|
|
|
function gh_callback_host(username, botname, gamename)
|
|
local gametype = "5x5"
|
|
if string.find(game.name, "3x3") then gametype = "3x3" end
|
|
|
|
gh_set_userbot(username, botname, gamename, gametype)
|
|
api.message_send_text(username, message_type_info, nil, localize(username, "Game \"{}\" is created by {}. You are an owner.", gamename, botname))
|
|
end
|
|
function gh_callback_chost(username, botname, gamename)
|
|
gh_set_userbot(username, botname, gamename, "")
|
|
api.message_send_text(username, message_type_info, nil, localize(username, "Game \"{}\" is created by {}. You are an owner.", gamename, botname))
|
|
end
|
|
|
|
|
|
function gh_callback_unhost(username, gamename)
|
|
gh_del_userbot(username)
|
|
api.message_send_text(username, message_type_info, nil, localize(username, "The game \"{}\" was destroyed.", gamename))
|
|
end
|
|
|
|
function gh_callback_ping(username, players, pings)
|
|
-- make sure that user is still in a game
|
|
local account = api.account_get_by_name(username)
|
|
local game = api.game_get_by_id(account.game_id)
|
|
if not next(game) then return end
|
|
-- make sure game owner is a bot
|
|
if not gh_is_bot(game.owner) then return end
|
|
|
|
-- get silent flag (do not send result to user)
|
|
-- it's needed to do not show ping when user join a game, but we want to save the ping into database
|
|
local silent = gh_get_silentflag(username)
|
|
|
|
local users = {}
|
|
|
|
i = 1
|
|
-- fill usernames
|
|
for v in string.split(players, ",") do
|
|
-- init each user table
|
|
users[i] = {}
|
|
users[i]["name"] = v
|
|
i = i + 1
|
|
end
|
|
i = 1
|
|
-- fill pings
|
|
for v in string.split(pings, ",") do
|
|
users[i]["ping"] = v
|
|
i = i + 1
|
|
end
|
|
|
|
local latency_all = ""
|
|
local ms = localize(username, "ms")
|
|
-- iterate each user
|
|
for i,u in pairs(users) do
|
|
-- load user pings
|
|
local pings = account_get_botping(u["name"])
|
|
local is_found = false
|
|
for k,v in pairs(pings) do
|
|
-- update user ping for current bot
|
|
if (v.bot == game.owner) then
|
|
pings[k].ping = u["ping"]
|
|
is_found = true
|
|
end
|
|
end
|
|
-- if bot not found in database pings then add a new row
|
|
if not is_found then
|
|
local item = {
|
|
date = os.time(),
|
|
bot = game.owner,
|
|
ping = u["ping"]
|
|
}
|
|
table.insert(pings, item)
|
|
end
|
|
|
|
-- save updated pings
|
|
account_set_botping(u["name"], pings)
|
|
|
|
latency_all = latency_all .. string.format("%s: [%s %s]; ", u["name"], u["ping"], ms)
|
|
|
|
-- if game started send ping of each players on a new line
|
|
if (game.status == game_status_started) and not (silent) then
|
|
api.message_send_text(username, message_type_info, nil, localize(username, "{}'s latency to {}: {} {}", u["name"], game.owner, u["ping"], ms))
|
|
end
|
|
end
|
|
|
|
-- if game not started send pings of all players in a single line
|
|
if not (game.status == game_status_started) and not (silent) then
|
|
api.message_send_text(username, message_type_info, nil, localize(username, "Latency: {}", latency_all))
|
|
end
|
|
end
|
|
|
|
|
|
function gh_callback_gameresult(players, ratings, results)
|
|
local users = {}
|
|
|
|
-- fill table users
|
|
i = 1
|
|
for v in string.split(players, ",") do
|
|
-- init each user table
|
|
users[i] = {}
|
|
users[i]["name"] = v
|
|
i = i + 1
|
|
end
|
|
i = 1
|
|
for v in string.split(ratings, ",") do
|
|
users[i]["rating"] = tonumber(v)
|
|
i = i + 1
|
|
end
|
|
i = 1
|
|
for v in string.split(results, ",") do
|
|
users[i]["result"] = tonumber(v)
|
|
i = i + 1
|
|
end
|
|
|
|
-- iterate each user
|
|
for i,u in pairs(users) do
|
|
local rating, wins, losses, leaves, streaks = 0,0,0,0,0
|
|
local gametype = ""
|
|
|
|
-- get stats
|
|
if #users == 6 then
|
|
gametype = "3x3"
|
|
rating = account_get_dotarating_3x3(u["name"])
|
|
wins = account_get_dotawins_3x3(u["name"])
|
|
losses = account_get_dotalosses_3x3(u["name"])
|
|
leaves = account_get_dotaleaves_3x3(u["name"])
|
|
streaks = account_get_dotastreaks_3x3(u["name"])
|
|
elseif #users == 10 then
|
|
gametype = "5x5"
|
|
rating = account_get_dotarating_5x5(u["name"])
|
|
wins = account_get_dotawins_5x5(u["name"])
|
|
losses = account_get_dotalosses_5x5(u["name"])
|
|
leaves = account_get_dotaleaves_5x5(u["name"])
|
|
streaks = account_get_dotastreaks_5x5(u["name"])
|
|
else
|
|
-- bad result
|
|
ERROR(string.format("Bad game result (%s %s %s)", players, ratings, results))
|
|
return
|
|
end
|
|
|
|
-- calc new stats
|
|
if u["result"] == 2 then -- leave & win
|
|
leaves = leaves + 1
|
|
wins = wins + 1
|
|
elseif u["result"] == 1 then -- win
|
|
wins = wins + 1
|
|
elseif u["result"] == 0 then -- loss
|
|
losses = losses + 1
|
|
elseif u["result"] == -1 then -- leave & loss
|
|
leaves = leaves + 1
|
|
losses = losses + 1
|
|
end
|
|
|
|
local result_str = localize(u["name"], "won")
|
|
|
|
if streaks >= 0 then -- win streak
|
|
if u["result"] > 0 then
|
|
streaks = streaks + 1
|
|
else
|
|
streaks = -1
|
|
end
|
|
else -- loss streak
|
|
if u["result"] <= 0 then
|
|
streaks = streaks - 1
|
|
else
|
|
streaks = 1
|
|
end
|
|
result_str = localize(u["name"], "lose")
|
|
end
|
|
|
|
-- update stats
|
|
if #users == 6 then
|
|
account_set_dotarating_3x3(u["name"], u["rating"])
|
|
account_set_dotawins_3x3(u["name"], wins)
|
|
account_set_dotalosses_3x3(u["name"], losses)
|
|
account_set_dotaleaves_3x3(u["name"], leaves)
|
|
account_set_dotastreaks_3x3(u["name"], streaks)
|
|
elseif #users == 10 then
|
|
account_set_dotarating_5x5(u["name"], u["rating"])
|
|
account_set_dotawins_5x5(u["name"], wins)
|
|
account_set_dotalosses_5x5(u["name"], losses)
|
|
account_set_dotaleaves_5x5(u["name"], leaves)
|
|
account_set_dotastreaks_5x5(u["name"], streaks)
|
|
end
|
|
|
|
-- diff between old and new rating
|
|
local points = u["rating"]-rating
|
|
|
|
-- inform user about new stats
|
|
api.message_send_text(u["name"], message_type_info, nil, localize(u["name"], "You {} {} points.", result_str, points))
|
|
api.message_send_text(u["name"], message_type_info, nil, localize(u["name"], "New DotA ({}) rating: {} pts. Current {} streak: {}", gametype, rating, result_str, streaks))
|
|
end
|
|
|
|
|
|
end
|