-- local JSON = require( "component/dkjson") --系统自带json -- local sha = require("libraries/sha") if Service == nil then Service = class({}) end -- 配置项 start SERVER_KEY = GetDedicatedServerKeyV2("mydota") REQUEST_TIME_OUT = 30 Service.Config = { ["admin"] = "ADMIN_STEAMID", ["gameCode"] = "dummy", ["urlGameConfig"] = "http://192.168.1.103:5000/api/GameConfig", ["urlPlayerData"] = "http://192.168.1.103:5000/api/PlayerData", ["urlRankData"] = "dummy", ["urlPlayerBaseData"] = "dummy" } -- 游戏配置项 GameRules.GameData = { ver = "S8", admin = Service.Config.admin, max_food = 12, code = "", -- 0000为正常完成,其它为错误发生 msg = "", -- 出错消息 game_code = "", game_msg = "", luck_card = "", luck_crit = 0, new_card_list = "", open_day_list = "", is_open_day = 0, server_time = GetRealDateTime(), } -- endregion -- 通用方法 start -- 通用请求,fTimeout超时秒,不传则默认;hFunc(iStatusCode, sBody) function Service:Request(method, url, hParams, hFunc, fTimeout) local handle = CreateHTTPRequestScriptVM(method, url) -- 需要放在Load阶段后,即DOTA_GAMERULES_STATE_CUSTOM_GAME_SETUP及以后阶段 handle:SetHTTPRequestHeaderValue("Content-Type", "application/json;charset=uft-8") if hParams == nil then hParams = {} end hParams.randomCode = tostring(RandomInt(1, 99999999)) hParams.serverKey = SERVER_KEY hParams.gameCode = self.Config.gameCode if method == "get" or method == "GET" then for k,v in pairs(hParams) do handle:SetHTTPRequestGetOrPostParameter(tostring(k), tostring(v)) end else handle:SetHTTPRequestRawPostBody("application/json", json.encode(hParams)) end handle:SetHTTPRequestAbsoluteTimeoutMS((fTimeout or REQUEST_TIME_OUT) * 1000) handle:Send(function(response) hFunc(response.StatusCode, response.Body) end) end -- 同步模式通用请求,需在 coroutine.wrap 中调用。 function Service:RequestSync(method, url, hParams, fTimeout) local co = coroutine.running() self:Request(method, url, hParams, function(iStatusCode, sBody) coroutine.resume(co, iStatusCode, sBody) end, fTimeout) return coroutine.yield() end function Service:Get(url, params, func) local req = CreateHTTPRequestScriptVM("GET", url) -- 需要放在Load阶段后,即DOTA_GAMERULES_STATE_CUSTOM_GAME_SETUP及以后阶段 if params == nil then params = {} end params.randomCode = RandomInt(1, 99999999) params.serverKey = SERVER_KEY params.gameCode = self.Config.gameCode for k,v in pairs(params) do req:SetHTTPRequestGetOrPostParameter(tostring(k), tostring(v)) end req:SetHTTPRequestAbsoluteTimeoutMS((REQUEST_TIME_OUT or 60) * 1000) req:Send(function(response) func(response.StatusCode, response.Body) end) end function Service:Post(url, data, func) local req = CreateHTTPRequestScriptVM("POST", url) -- 需要放在Load阶段后,即DOTA_GAMERULES_STATE_CUSTOM_GAME_SETUP及以后阶段 req:SetHTTPRequestHeaderValue("Content-Type", "application/json;charset=uft-8") if data == nil then data = {} end data.serverKey = SERVER_KEY data.gameCode = self.Config.gameCode req:SetHTTPRequestRawPostBody("application/json", json.encode(data)) req:SetHTTPRequestAbsoluteTimeoutMS((REQUEST_TIME_OUT or 60) * 1000) req:Send(function(response) func(response.StatusCode, response.Body) end) end -- endregion -- 编码 start -- 卡组数据明细解码,hex编码的卡组名称#卡牌及数量#卡牌及数量#...,卡牌及数量为卡牌物品后4位加数量,如00011表示item_0001,数量1个。 -- 输入 string: e68891e79a84e58da1e7bb84#20084#00023#00801#00922#000410#00571#20044#20194#20204 -- 返回 data : {"name":"我的卡组","item_2008":4,"item_0002":3,"item_0080":1,"item_0092":2,...} function Service:decodeCardGroup(cardString) local retData = {} if cardString == nil or cardString == "" then return retData end local a = string.split(cardString, "#") if a == nil or #a < 2 then return retData end retData["name"] = string.fromhex(a[1]) for i=2, #a do retData["item_"..string.sub(a[i],1,4)] = tonumber(string.sub(a[i],5,6)) end return retData end -- 卡组数据明细编码,hex编码的卡组名称#卡牌及数量#卡牌及数量#...,卡牌及数量为卡牌物品后4位加数量,如00011表示item_0001,数量1个。 -- 输入data = {"name":"我的卡组","item_2008":4,"item_0002":3,"item_0080":1,"item_0092":2,...} -- 返回string: e68891e79a84e58da1e7bb84#20084#00023#00801#00922#000410#00571#20044#20194#20204#00583#20174#00362#20074#00522#20154#20241#20014#20064#00885#20231#00077#20164#00068#00973#00341#00962#20021#00162#00412 function Service:encodeCardGroup(cardGroup) local retString = "" if cardGroup["name"] ~= nil then retString = string.tohex(cardGroup["name"]) end for k,v in pairs(cardGroup) do if k ~= "name" then retString = retString.."#"..string.sub(k,6,9)..tostring(v) end end return retString end -- 等级解码 function Service:decodeCardLevel(cardString) local retData = {} if cardString == nil or cardString == "" then return retData end local a = string.split(cardString, "#") if a == nil or #a < 1 then return retData end for i=1, #a do retData["item_0"..string.sub(a[i],1,3)] = tonumber(string.sub(a[i],4,9)) end return retData end -- 等级编码 function Service:encodeCardLevel(cardLevel) local retString = "" for k,v in pairs(cardLevel) do if retString == "" then retString = string.sub(k,7,9)..tostring(v) elseif v ~= nil then retString = retString.."#"..string.sub(k,7,9)..tostring(v) end end return retString end -- endregion -- 加载游戏数据 start -- 获取游戏用户数据,按顺序 function Service:LoadGameData() coroutine.wrap(function() print("----> start request game config : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) local iStatusCode, sBody = Service:RequestSync("get", self.Config.urlGameConfig) print("<---- end request game config : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) self:InitGameConfig(iStatusCode, sBody) local input = {method = "get", ids = {}} for i=0, PlayerResource:GetPlayerCount()-1 do input.ids[i] = tostring(PlayerResource:GetSteamID(i)) end print("----> start request player data : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) local iStatusCode, sBody = Service:RequestSync("post", self.Config.urlPlayerData, input) print("<---- end request player data : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) self:InitPlayerData(iStatusCode, sBody, input) end)() end -- 游戏配置 function Service:InitGameConfig(iStatusCode, sBody) if iStatusCode == 200 then local data = json.decode(sBody) if data then GameRules.GameData.code = data.code GameRules.GameData.msg = data.msg GameRules.GameData.game_code = data.game_code or "" GameRules.GameData.game_msg = data.game_msg or "" GameRules.GameData.luck_card = data.luck_card or "" GameRules.GameData.luck_crit = data.luck_crit or 0 GameRules.GameData.new_card_list = data.new_card_list or "" GameRules.GameData.open_day_list = data.open_day_list or "" GameRules.GameData.is_open_day = data.is_open_day or 0 GameRules.GameData.server_time = data.server_time else GameRules.GameData.code = "0003" GameRules.GameData.msg = "游戏配置数据解析失败" end else GameRules.GameData.code = "0004" GameRules.GameData.msg = "无法访问服务器" end CustomNetTables:SetTableValue("CustomGameInfo", "GameData", GameRules.GameData) end -- 玩家数据 function Service:InitPlayerData(iStatusCode, sBody, input) if iStatusCode == 200 then local data = json.decode(sBody) if data then for k,v in pairs(data.bo) do --for i=1,20 do -- v["cardgroup"..i] = self:decodeCardGroup(v["cardgroup"..i]) --end v["level_list"] = self:decodeCardLevel(v["level_list"]) local index = tonumber(k) for key,value in pairs(v) do GameRules.PlayerData[index][key] = value end end else for k,v in pairs(input.ids) do GameRules.PlayerData[k].code = "0003" GameRules.PlayerData[k].msg = "用户数据解析失败" end end else for k,v in pairs(input.ids) do GameRules.PlayerData[k].code = "0004" GameRules.PlayerData[k].msg = "无法访问服务器" end end for k,v in pairs(input.ids) do CustomNetTables:SetTableValue("CustomGameInfo", "PlayerData_"..v, GameRules.PlayerData[k]) -- print("--------- PlayerData "..tostring(k)) -- DeepPrintTable(GameRules.PlayerData[k]) end end -- endregion -- 加载排行榜数据 start -- 获取排行榜通用方法 function Service:GetRank(rankType) -- 初始化 if GameRules.players_rank_ok == nil then GameRules.players_rank_ok = false -- 是否载入成功 GameRules.players_rank = {} -- 排行榜基本数据 GameRules.players_rank_data = {} -- 排行榜明细数据 GameRules.players_team_rank = {} GameRules.players_team_rank_data = {} end print("----> start request get rank : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) local input = {} input["rank_type"] = rankType or "all" --或取值SDT中一个, S 原始榜,D 巅峰榜,T 挑战榜 self:Get( self.Config.urlRankData, input, function(iStatusCode, sBody) print("<---- end request get rank : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) if iStatusCode == 200 then local data = json.decode(sBody) if data then if data.code == "0000" then GameRules.players_rank_ok = true local datas = data.bo["S"] if #datas > 0 then local ranks = {} for i = 1, #datas do ranks[i] = { ['steamid'] = datas[i].steamid, ['userid'] = datas[i].userid, ['username'] = string.fromhex(datas[i].username), ['wave'] = datas[i].wave, ['damage'] = datas[i].damage, ['version'] = datas[i].version, ['host'] = datas[i].host, ['updatetime'] = datas[i].update_time } for k,v in pairs(datas[i]) do if string.sub(k,1,4) == "card" then datas[i][k] = json.decode(string.fromhex(v)) end end for id=0, PlayerResource:GetPlayerCount()-1 do if PlayerResource:IsValidPlayerID(id) then if GameRules.PlayerData[id].steamid == datas[i].steamid then GameRules.PlayerData[id].max_wave = datas[i].wave print("----- 玩家"..tostring(id).."原始榜波数:"..tostring(datas[i].wave)) break end end end end GameRules.players_rank = ranks GameRules.players_rank_data = datas ranks = {} datas = {} CustomNetTables:SetTableValue("CustomGameInfo", "PlayersRank", GameRules.players_rank) end local datas = data.bo["D"] if #datas > 0 then local ranks = {} for i = 1, #datas do ranks[i] = { ['steamid'] = datas[i].steamid, ['userid'] = datas[i].userid, ['username'] = string.fromhex(datas[i].username), ['wave'] = datas[i].wave, ['damage'] = datas[i].damage, ['version'] = datas[i].version, ['host'] = datas[i].host, ['updatetime'] = datas[i].update_time } for k,v in pairs(datas[i]) do if string.sub(k,1,4) == "card" then datas[i][k] = json.decode(string.fromhex(v)) end end for id=0, PlayerResource:GetPlayerCount()-1 do if PlayerResource:IsValidPlayerID(id) then if GameRules.PlayerData[id].steamid == datas[i].steamid then GameRules.PlayerData[id].max_team_wave = datas[i].wave print("----- 玩家"..tostring(id).."巅峰榜波数:"..tostring(datas[i].wave)) break end end end end GameRules.players_team_rank = ranks GameRules.players_team_rank_data = datas ranks = {} datas = {} CustomNetTables:SetTableValue("CustomGameInfo", "PlayersTeamRank", GameRules.players_team_rank) end else CustomGameEventManager:Send_ServerToAllClients("thtd_server_msg", {code = "0005", msg = data.msg, duration = 10, pos = 200}) end else CustomGameEventManager:Send_ServerToAllClients("thtd_server_msg", {code = "0003", msg = "获取排行榜数据出错,本次游戏将无法上传原始榜,数据解析失败", duration = 10, pos = 200}) end else CustomGameEventManager:Send_ServerToAllClients("thtd_server_msg", {code = "0004", msg = "获取排行榜数据出错,本次游戏将无法上传原始榜,StatusCode: "..tostring(iStatusCode), duration = 10, pos = 200}) end end ) end -- 重置排行榜 function Service:ResetRank(index, rankType) print("----> start request reset rank : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) local input = {method = "reset"} input["rank_type"] = rankType if rankType == "S" then input["steamid"] = GameRules.players_rank[index].steamid input["userid"] = GameRules.players_rank[index].userid elseif rankType == "D" then input["steamid"] = GameRules.players_team_rank[index].steamid input["userid"] = GameRules.players_team_rank[index].userid else return end self:Post( self.Config.urlRankData, input, function(iStatusCode, sBody) print("<---- end request reset rank : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) if iStatusCode == 200 then local data = json.decode(sBody) if data then if data.code == "0000" then if rankType == "S" then CustomGameEventManager:Send_ServerToAllClients("thtd_reset_rank", {index = index, msg = ""}) elseif rankType == "D" then CustomGameEventManager:Send_ServerToAllClients("thtd_reset_team_rank", {index = index, msg = ""}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = data.code, msg = "重置排行榜失败,"..data.msg, duration = 5, pos = 100}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = "0003", msg = "重置排行榜失败,无法解析数据", duration = 5, pos = 100}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = "0004", msg = "重置排行榜失败,无法连接服务器", duration = 5, pos = 100}) end end ) end -- 上传排行榜 function Service:UploadRank(playerId, rankType, wavedata) print("----> start request upload rank : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) local steamid = tostring(PlayerResource:GetSteamID(playerId)) local input = {method = "update"} input["rank_type"] = rankType input["steamid"] = steamid input["userid"] = tostring(PlayerResource:GetSteamAccountID(playerId)) input["username"] = string.tohex(PlayerResource:GetPlayerName(playerId)) input["version"] = GameRules.GameData.ver input["wave"] = wavedata["wave"] input["damage"] = wavedata["damage"] for k,v in pairs(wavedata) do if string.sub(k,1,4) == "card" then input[k] = string.tohex(json.encode(v)) end end local teamText = "" if rankType == "D" then teamText = "巅峰" elseif rankType == "S" then teamText = "原始" end local bonus = 10 if wavedata["rank_index"] <= 4 then bonus = 500 - (wavedata["rank_index"] - 1) * 100 elseif wavedata["rank_index"] <= 9 then bonus = 170 - (wavedata["rank_index"] - 5) * 10 elseif wavedata["rank_index"] <= 15 then bonus = 125 - (wavedata["rank_index"] - 10) * 5 elseif wavedata["rank_index"] <= 25 then bonus = 96 - (wavedata["rank_index"] - 16) * 4 elseif wavedata["rank_index"] <= 50 then bonus = 58 - (wavedata["rank_index"] - 26) * 2 end CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = "0000", msg = "恭喜上榜,排名:".. wavedata["rank_index"] ..",此排名赛季结算奖励:符卡精华 ×"..tostring(bonus), duration = 30, pos = -100}) self:Post( self.Config.urlRankData, input, function(iStatusCode, sBody) print("<---- end request upload rank : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) if iStatusCode == 200 then local data = json.decode(sBody) if data then if data.code == "0000" then CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = "0000", msg = "恭喜!你打破了历史记录,达到了新的最高波数,上传"..teamText.."排行榜成功!", duration = 30}) if SpawnSystem:GetCount() == 0 then Service:ClearSameRank() end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = data.code, msg = "上传排行榜失败,"..data.msg, duration = 10}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = "0003", msg = "上传排行榜失败,无法解析数据", duration = 10}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = "0004",msg = "上传排行榜失败,无法连接服务器", duration = 10}) end end ) end -- 清除相同的排行榜 function Service:ClearSameRank() if GameRules.GameData.is_clear_rank == true then return end GameRules.GameData.is_clear_rank = true local toplist local isTeam = GameRules.HeroList[0].is_team_mode if isTeam == true then toplist = GameRules.players_team_rank_data else toplist = GameRules.players_rank_data end if #toplist == 0 then return end local toDelList = {} for i=1,#toplist-1 do local wavedata = toplist[i] if table.hasvalue(toDelList, i) == false then for j=i+1,#toplist do local topdata = toplist[j] local isSameRank = false if wavedata["card1"] ~= "" and wavedata["card1"] ~= nil and topdata["card1"] ~= "" and topdata["card1"] ~= nil and wavedata["card1"]["itemname"] == topdata["card1"]["itemname"] then if wavedata["card1"]["damage"] / (10000 * wavedata["damage"]) >= 0.6 and topdata["card1"]["damage"] / (10000 * topdata["damage"]) >= 0.6 then isSameRank = true end end if isSameRank == false then local topDamage1 = 0 local topDamage2 = 0 local topNum = 0 for x=1,12 do if wavedata["card"..tostring(x)] ~= "" and wavedata["card"..tostring(x)] ~= nil then topDamage1 = topDamage1 + wavedata["card"..tostring(x)]["damage"] end if topdata["card"..tostring(x)] ~= "" and topdata["card"..tostring(x)] ~= nil then topDamage2 = topDamage2 + topdata["card"..tostring(x)]["damage"] end if topDamage1 / (10000 * wavedata["damage"]) >= 0.8 and topDamage2 / (10000 * topdata["damage"]) >= 0.8 then topNum = x break end end if topNum > 0 then local sameCount = 0 local usedIndex = "" for x=1,topNum do for y=1,topNum do if string.find(usedIndex,tostring(y)) == nil and wavedata["card"..tostring(x)] ~= "" and topdata["card"..tostring(y)] ~= "" and topdata["card"..tostring(y)] ~= nil and wavedata["card"..tostring(x)]["itemname"] == topdata["card"..tostring(y)]["itemname"] then sameCount = sameCount + 1 usedIndex = usedIndex..tostring(y).."," break end end end if sameCount == topNum then isSameRank = true end end end if isSameRank == true then table.insert(toDelList, j) end end end end for k,v in pairs(toDelList) do if isTeam == true then Service:ResetRank(v, "D") else Service:ResetRank(v, "S") end end print("---------- the same rank : ", json.encode(toDelList)) end -- endregion -- 玩家数据 start -- 保存玩家卡组 function Service:SaveCardGroup(playerId, groupKey, groupData) print("----> start request save card group : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) local steamid = tostring(PlayerResource:GetSteamID(playerId)) local input = {method = "save_card_group"} input["steamid"] = steamid input["userid"] = tostring(PlayerResource:GetSteamAccountID(playerId)) input["group_key"] = groupKey input["group_data"] = self:encodeCardGroup(groupData) self:Post( self.Config.urlPlayerData, input, function(iStatusCode, sBody) print("<---- end request save card group : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) if iStatusCode == 200 then local data = json.decode(sBody) if data then if data.code == "0000" then CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_save_cardgroup", {code = data.code, msg = ""}) GameRules.PlayerData[playerId][groupKey] = groupData CustomNetTables:SetTableValue("CustomGameInfo", "PlayerData_"..steamid, GameRules.PlayerData[playerId]) else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_save_cardgroup", {code = data.code, msg = data.msg}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_save_cardgroup", {code = "0005", msg = "数据解析失败:"..sBody}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_save_cardgroup", {code = "0009", msg = "无法连接服务器,StatusCode: "..tostring(iStatusCode)}) end end ) end -- 获取玩家基础数据 function Service:GetPlayerBaseData(playerId) local steamid = tostring(PlayerResource:GetSteamID(playerId)) print("----> start request player base data : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) self:Get( self.Config.urlPlayerBaseData, {id = steamid}, function(iStatusCode, sBody) print("<---- end request player base data : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) if iStatusCode == 200 then local data = json.decode(sBody) if data then if data.code == "0000" then self:UpdatePlayerData(playerId, data) end CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_update_player_data", data) else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_update_player_data", {code = "0003", msg = "返回数据解析失败"}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_update_player_data", {code = "0004", msg = "无法连接服务器,StatusCode: "..tostring(iStatusCode)}) end end ) end -- 更新玩家基础数据信息 function Service:UpdatePlayerData(playerId, data) GameRules.PlayerData[playerId].point = data.point GameRules.PlayerData[playerId].level_list = self:decodeCardLevel(data.level_list) GameRules.PlayerData[playerId].pet_level = data.pet_level GameRules.PlayerData[playerId].end_time = data.end_time GameRules.PlayerData[playerId].key_total = data.key_total GameRules.PlayerData[playerId].key_save_date = data.key_save_date GameRules.PlayerData[playerId].vip = data.vip if GameRules:State_Get() == DOTA_GAMERULES_STATE_GAME_IN_PROGRESS then -- 更新宠物等级 local hero = GameRules.HeroList[playerId] local pet = hero.reimu_pet if pet ~= nil and pet.pet_level ~= data.pet_level then local oldLevel = pet.pet_level pet.pet_level = data.pet_level pet:FindModifierByName("modifier_reimu_pet_01_level"):SetStackCount(data.pet_level) pet:CreatureLevelUp(data.pet_level - oldLevel) end -- 更新钥匙数量 local item = hero:FindItemInInventory("item_3121") if item ~= nil then if data.key_total ~= item:GetCurrentCharges() then item:SetCurrentCharges(data.key_total) if data.key_total <= 0 then hero:RemoveItem(item) end end elseif data.key_total > 0 then item = CreateItem("item_3121", nil, nil) if item ~= nil then item.owner_player_id = playerId item:SetPurchaser(hero) item:SetCurrentCharges(data.key_total) hero:AddItem(item) end end end CustomNetTables:SetTableValue("CustomGameInfo", "PlayerData_"..tostring(PlayerResource:GetSteamID(playerId)), GameRules.PlayerData[playerId]) end -- 培养卡牌 function Service:SaveCardLevel(playerId, card, level) print("----> start request save card group : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) local steamid = tostring(PlayerResource:GetSteamID(playerId)) local input = {method = "save_card_level"} input["steamid"] = steamid input["userid"] = tostring(PlayerResource:GetSteamAccountID(playerId)) input["card"] = card --item_0001 input["level"] = level --增加等级 self:Post( self.Config.urlPlayerData, input, function(iStatusCode, sBody) print("<---- end request save card group : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) if iStatusCode == 200 then local data = json.decode(sBody) if data then if data.code == "0000" then GameRules.PlayerData[playerId].point = GameRules.PlayerData[playerId].point - data.cost_point GameRules.PlayerData[playerId]["level_list"][card] = (GameRules.PlayerData[playerId]["level_list"][card] or 0) + level CustomNetTables:SetTableValue("CustomGameInfo", "PlayerData_"..steamid, GameRules.PlayerData[playerId]) CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_update_game_point", {point = GameRules.PlayerData[playerId].point}) data.level_list = GameRules.PlayerData[playerId]["level_list"] end CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_train_card_complete", data) else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_train_card_complete", {code = "0003", msg = "返回数据解析失败"}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_train_card_complete", {code = "0004", msg = "无法连接服务器,StatusCode: "..tostring(iStatusCode)}) end end ) end -- 保存宠物 function Service:SavePetCustom(playerId) print("----> start request save pet custom : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) local steamid = tostring(PlayerResource:GetSteamID(playerId)) local input = {method = "save_pet_custom"} input["steamid"] = steamid input["userid"] = tostring(PlayerResource:GetSteamAccountID(playerId)) input["pet_model"] = GameRules.PlayerData[playerId].pet_model input["pet_effect"] = GameRules.PlayerData[playerId].pet_effect self:Post( self.Config.urlPlayerData, input, function(iStatusCode, sBody) print("<---- end request save pet custom : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) if iStatusCode == 200 then local data = json.decode(sBody) if data then if data.code == "0000" then CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "show_message", {msg="pet_cumstom_saved", duration=15, params={}, color="#ff0"}) else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = data.code, msg = data.msg}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "display_custom_error", {msg="user_server_error"}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "display_custom_error", {msg="connect_server_error"}) end end ) end -- 购买魔法钥匙 function Service:BuyMagicKey(playerId, count) print("----> start request buy magic key : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) local steamid = tostring(PlayerResource:GetSteamID(playerId)) local input = {method = "buy_key"} input["steamid"] = steamid input["userid"] = tostring(PlayerResource:GetSteamAccountID(playerId)) input["count"] = count self:Post( self.Config.urlPlayerData, input, function(iStatusCode, sBody) print("<---- end request buy magic key : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) if iStatusCode == 200 then local data = json.decode(sBody) if data then if data.code == "0000" then GameRules.PlayerData[playerId]["point"] = GameRules.PlayerData[playerId]["point"] - data.cost_point CustomNetTables:SetTableValue("CustomGameInfo", "PlayerData_"..steamid, GameRules.PlayerData[playerId]) CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_update_game_point", {point = GameRules.PlayerData[playerId]["point"]}) local hero = GameRules.HeroList[playerId] local item = hero:FindItemInInventory("item_3121") if item ~= nil then item:SetCurrentCharges(item:GetCurrentCharges() + count) else item = CreateItem("item_3121", nil, nil) if item ~= nil then item.owner_player_id = playerId item:SetPurchaser(hero) item:SetCurrentCharges(count) hero:AddItem(item) end end CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "show_message", {msg="key_made_tip", duration=3, params={}, color="#ff0"}) ParticleManager:DestroyParticleSystem(hero.thtd_emoji_effect,true) hero.thtd_emoji_effect = ParticleManager:CreateParticle("particles/thtd/emoji/thtd_msg_hongliange.vpcf", PATTACH_OVERHEAD_FOLLOW, hero) ParticleManager:SetParticleControlEnt(hero.thtd_emoji_effect , 0, hero, PATTACH_OVERHEAD_FOLLOW, "attach_hitloc", Vector(0,0,0), true) --灵梦用 attach_emoji ParticleManager:SetParticleControl(hero.thtd_emoji_effect, 3, Vector(1,0,0)) ParticleManager:DestroyParticleSystemTime(hero.thtd_emoji_effect,5.0) else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = data.code, msg = "购买钥匙失败,"..data.msg}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "display_custom_error", {msg="user_server_error"}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "display_custom_error", {msg="connect_server_error"}) end end ) end -- 保存魔法钥匙 function Service:SaveKeyCount(playerId) if GameRules.PlayerData[playerId].code ~= "0000" then return end local keyCount = 0 local hero = GameRules.HeroList[playerId] local itemTpSlot = hero:GetItemInSlot(DOTA_ITEM_TP_SCROLL) --15 if itemTpSlot then keyCount = itemTpSlot:GetCurrentCharges() end if keyCount == GameRules.PlayerData[playerId]["key_total"] then return end print("----> start request save key count : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) local steamid = tostring(PlayerResource:GetSteamID(playerId)) local input = {method = "save_key_count"} input["steamid"] = steamid input["userid"] = tostring(PlayerResource:GetSteamAccountID(playerId)) input["key_total"] = keyCount input["key_use_count"] = GameRules.PlayerData[playerId]["key_use_count"] self:Post( self.Config.urlPlayerData, input, function(iStatusCode, sBody) print("<---- end request save key count : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) if iStatusCode == 200 then local data = json.decode(sBody) if data then if data.code == "0000" then GameRules.PlayerData[playerId]["key_total"] = keyCount else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = data.code, msg = "保存钥匙数量失败,"..data.msg, duration = 10, pos = 150}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = "0003", msg = "保存钥匙数量失败,无法解析数据", duration = 10, pos = 150}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = "0004", msg = "保存钥匙数量失败,无法连接服务器", duration = 10, pos = 150}) end end ) end -- 保存凤凰之灵 function Service:SavePowerMaxCount(playerId, isAdd) print("----> start request save power max count : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) local steamid = tostring(PlayerResource:GetSteamID(playerId)) local input = {method = "save_power_max"} input["steamid"] = steamid input["userid"] = tostring(PlayerResource:GetSteamAccountID(playerId)) if isAdd == true then input["op"] = "add" else input["op"] = "sub" end self:Post( self.Config.urlPlayerData, input, function(iStatusCode, sBody) print("<---- end request save power max count : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) if iStatusCode == 200 then local data = json.decode(sBody) if data then if data.code == "0000" then print("----- 玩家"..tostring(playerId).."的凤凰之灵已保存") else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = data.code, msg = "保存凤凰之灵失败,"..data.msg, duration = 10}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = "0003", msg = "保存凤凰之灵失败,无法解析数据", duration = 10}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = "0004", msg = "保存凤凰之灵失败,无法连接服务器", duration = 10}) end end ) end -- 首胜奖励 function Service:GiveDayFirstWinBonus(playerId) print("----> start request day first win : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) local steamid = tostring(PlayerResource:GetSteamID(playerId)) local input = {method = "day_first_win"} input["steamid"] = steamid input["userid"] = tostring(PlayerResource:GetSteamAccountID(playerId)) self:Post( self.Config.urlPlayerData, input, function(iStatusCode, sBody) print("<---- end request day first win : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) if iStatusCode == 200 then local data = json.decode(sBody) if data then if data.code == "0000" then GameRules.PlayerData[playerId]["point"] = GameRules.PlayerData[playerId]["point"] + data.bonus_point CustomNetTables:SetTableValue("CustomGameInfo", "PlayerData_"..steamid, GameRules.PlayerData[playerId]) CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_update_game_point", {point = GameRules.PlayerData[playerId]["point"]}) CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = "0000", msg = "获得 符卡精华 x"..tostring(data.bonus_point)}) else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = data.code, msg = "每日开箱奖励失败,"..data.msg}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = "0003", msg = "每日开箱奖励失败,无法解析数据"}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_server_msg", {code = "0004", msg = "每日开箱奖励失败,无法连接服务器"}) end end ) end -- endregion -- 赞助 start -- 创建订单 function Service:CreateShopOrder(playerId, payType, amount, price, goods) print("----> start request buy order : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) local current = 0 local tips = "" if goods == "fairy" then current = GameRules.PlayerData[playerId].point tips = "获得:符卡精华 ×"..tostring(amount) elseif goods == "pet" then current = GameRules.PlayerData[playerId].pet_level tips = "宠物等级提升 "..tostring(amount).." 级,特别奖励时间增加 "..tostring(amount*2).." 个月" end local steamid = tostring(PlayerResource:GetSteamID(playerId)) local input = {method = "create_shop_order"} input["steamid"] = steamid input["userid"] = tostring(PlayerResource:GetSteamAccountID(playerId)) input["pay_type"] = payType -- 1支付宝,2微信 input["amount"] = amount -- 订单数量 input["price"] = price -- 价格,整数,分 input["goods"] = goods -- 商品 input["current"] = current -- 当前数量 GameRules.PlayerData[playerId].order_tips = "没有生成订单" self:Post( self.Config.urlPlayerData, input, function(iStatusCode, sBody) print("<---- end request buy order : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) if iStatusCode == 200 then local data = json.decode(sBody) if data then if data.code == "0000" then GameRules.PlayerData[playerId].order_no = data.order_no GameRules.PlayerData[playerId].order_tips = tips CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_pay_post", {code = 1, method = payType}) local time = 45 local tick = 1.5 GameRules:GetGameModeEntity():SetContextThink(DoUniqueString("Query_Order_State"), function() if GameRules.PlayerData[playerId].order_no == nil then return nil end if time < 0 then return nil end self:PayAutoCheck(playerId) time = time - tick return tick end, tick) else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_pay_post", {code = 505, msg = data.msg}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_pay_post", {code = 505, msg = "无法解析数据,"..sBody}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_pay_post", {code = 201, msg = "无法连接,StatusCode: "..tostring(iStatusCode)}) end end ) end -- 支付检查,自动模式 function Service:PayAutoCheck(playerId) if GameRules.PlayerData[playerId].order_no == nil then return end if GameRules.PlayerData[playerId].query_order == 1 then return end GameRules.PlayerData[playerId].query_order = 1 print("----> start request query pay order : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) local steamid = tostring(PlayerResource:GetSteamID(playerId)) local input = {method = "query_order"} input["steamid"] = steamid input["userid"] = tostring(PlayerResource:GetSteamAccountID(playerId)) input["order_no"] = GameRules.PlayerData[playerId].order_no self:Post( self.Config.urlPlayerData, input, function(iStatusCode, sBody) print("<---- end request query pay order : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) GameRules.PlayerData[playerId].query_order = nil if iStatusCode == 200 then local data = json.decode(sBody) if data then if data.code == "0000" then data.msg = GameRules.PlayerData[playerId].order_tips GameRules.PlayerData[playerId].order_no = nil GameRules.PlayerData[playerId].order_tips = "订单已经处理完成" self:UpdatePlayerData(playerId, data) data.hide = 1 CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_update_player_data", data) CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_pay_result", data) end end end end ) end -- 支付检查 function Service:PayCheck(playerId) if GameRules.PlayerData[playerId].order_no == nil then local data = {code = "0001", msg = GameRules.PlayerData[playerId].order_tips} if data.msg == "订单已经处理完成" then data.code = "0000" end CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_pay_result", data) return end print("----> start request query pay order : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) local steamid = tostring(PlayerResource:GetSteamID(playerId)) local input = {method = "query_order"} input["steamid"] = steamid input["userid"] = tostring(PlayerResource:GetSteamAccountID(playerId)) input["order_no"] = GameRules.PlayerData[playerId].order_no self:Post( self.Config.urlPlayerData, input, function(iStatusCode, sBody) print("<---- end request query pay order : ", tostring(math.floor(GameRules:GetGameTime()*100 + 0.5)/100)) if iStatusCode == 200 then local data = json.decode(sBody) if data then if data.code == "0000" then data.msg = GameRules.PlayerData[playerId].order_tips GameRules.PlayerData[playerId].order_no = nil GameRules.PlayerData[playerId].order_tips = "订单已经处理完成" self:UpdatePlayerData(playerId, data) data.hide = 1 CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_update_player_data", data) end CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_pay_result", data) else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_pay_result", {code = "0003", msg = "查询订单返回数据解析失败,稍后会人工处理,处理完请点击刷新即可,加急请进群联系作者", hide = hideMsg}) end else CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerId), "thtd_pay_result", {code = "0004", msg = "查询订单无法连接服务器,稍后会人工处理,处理完请点击刷新即可,加急请进群联系作者", hide = hideMsg}) end end ) end -- endregion