@@ -0,0 +1,42 @@ | |||
local Config = {} | |||
--开启测试登入模式 | |||
Config.isDebugLogion = false | |||
--关闭更新设置 | |||
Config.isCloseUpdate = false | |||
-- Rom中固化的设置 | |||
Config.RomSetting = loadRomSettingScript() | |||
-- 其他配置 | |||
Config.Setting = require("luaScript.Config.Setting") | |||
-- 子游戏配置信息 | |||
Config.SubGameConfigs = {} | |||
for _, gameId in pairs(GAME_IDS) do | |||
local filePath = string.format("luaScript/Config/SubGame/GameConfig_%03d", gameId) | |||
if isLuaFuleExist(filePath) then | |||
local strFileName = string.format("luaScript.Config.SubGame.GameConfig_%03d", gameId) | |||
local config = require(strFileName) | |||
Config.SubGameConfigs[gameId] = config | |||
end | |||
end | |||
local DefaultModuleConfig = require("luaScript.Config.DefaultModuleConfig") | |||
--当前项目的配置(没有写默认用core的) | |||
local moduleConfig = nil | |||
if cc.FileUtils:getInstance():isFileExist("luaScript/Config/ModuleConfig.luac") or | |||
cc.FileUtils:getInstance():isFileExist("luaScript/Config/ModuleConfig.lua") then | |||
moduleConfig = require("luaScript.Config.ModuleConfig") | |||
end | |||
for k, v in pairs(moduleConfig or {}) do | |||
DefaultModuleConfig[k] = v | |||
end | |||
Config.ModuleConfig = DefaultModuleConfig; | |||
return Config; |
@@ -0,0 +1,49 @@ | |||
-- --------------------- | |||
-- 大厅功能模块开关配置 | |||
-- 该文件只是默认配置,需要修改其中个别配置,请在平台Config目录下新增ModuleConfig.lua | |||
-- 并按下面格式,返回指定的开关配置即可,无需全部重写 | |||
-- --------------------- | |||
local ModuleConfig = {} | |||
-- 是否支持红包券功能 | |||
ModuleConfig.IsSupportHongBaoKa = true | |||
-- 是否支持金币场功能 | |||
ModuleConfig.IsSupportCoin = true | |||
-- 是否支持合伙人功能 | |||
ModuleConfig.IsSupportHeHuoRen = true | |||
-- 是否支持邀请拉新功能 | |||
ModuleConfig.IsSupportInviteNewFriend = true | |||
-- 是否支持金币场免费金币功能 | |||
ModuleConfig.IsSupportCoinFreeCoin = false | |||
-- 大厅红点管理 | |||
ModuleConfig.IsSupportRedPoint = false | |||
-- 是否支持比赛场功能 | |||
ModuleConfig.IsSupportMatch = false | |||
-- 是否支持道具商城显示 | |||
ModuleConfig.IsSupportPropShop = false | |||
-- 是否支持排位赛功能 | |||
ModuleConfig.IsSupportDaLianMeng = false | |||
-- 是否支持网页战绩 | |||
ModuleConfig.IsSupportZhanJiUrl = true | |||
-- 是否支持官方活动 | |||
ModuleConfig.IsSupportOfficeActivity = true | |||
-- 是否支持地区选择 | |||
ModuleConfig.IsSupportAddressSelector = false | |||
ModuleConfig.IsSupportMatchTuoGuan = false | |||
--是否支持悠闲豆 | |||
ModuleConfig.IsSupportYouXianBean = false | |||
---------------俱乐部--------------- | |||
-- 是否支持俱乐部桌子列表分页功能 | |||
ModuleConfig.IsSupportGetClubTableListWithPage = false | |||
--是否支持排名赛 | |||
ModuleConfig.IsSupportRankMatch = true | |||
--是否支持合盟 | |||
ModuleConfig.IsSupportUnion = false | |||
--是否支持普通场排行榜/上报排名 | |||
ModuleConfig.IsSupportNormalRank = false | |||
--是否支持三级合伙人(默认不支持,暂对重庆开启) | |||
ModuleConfig.IsSupportThirdCopartner = false | |||
return ModuleConfig |
@@ -0,0 +1,28 @@ | |||
-- ¶à΢ÐŲÎÊý | |||
local config = { | |||
--[[ | |||
{ | |||
appId = "wx9e0654fad4ac27c4", | |||
appKey = "e820dfdd8b295e34d9ad79448d2ee2a4", | |||
}, | |||
{ | |||
appId = "wxbe12c718df257ff0", | |||
appKey = "1c5445ba52c397802194420962c2a30c", | |||
}, | |||
{ | |||
appId = "wxa8a89f416bc9f968", | |||
appKey = "cc43ae995b7971e4223096e07bc7cd77", | |||
}, | |||
{ | |||
appId = "wxcc01cfef43acd4ee", | |||
appKey = "976fbe75dc0eae0a7c4f1ebdb07ef54e", | |||
}, | |||
{ | |||
appId = "wx1dafec29f245318b", | |||
appKey = "8d3baaf38f6ace6d8da32d2cd8ebad8e", | |||
} | |||
--]] | |||
}; | |||
return config; |
@@ -0,0 +1,15 @@ | |||
local setting = { | |||
-- 资源版本号 | |||
ResourceVersion = "1000"; | |||
-- IpServer | |||
IpServer = "http://shibaip.dingdingqipai.com/iplist.php", | |||
-- 官方下载地址 | |||
-- app.config.Setting.appDownloadUrl | |||
appDownloadUrl = "http://m.dingdingqipai.com/cnzp.php", | |||
}; | |||
return setting; |
@@ -0,0 +1,61 @@ | |||
cc.Point = cc.Point or {} | |||
cc.Color4F = cc.Color4F or {} | |||
cc.Color3B = cc.Color3B or {} | |||
cc.Size = cc.Size or {} | |||
cc.Rect = cc.Rect or {} | |||
cc.Margin = cc.Margin or {} | |||
function cc.Point:toString() | |||
return tostring(self.x) .. " " .. tostring(self.y); | |||
end | |||
function cc.Point.fromString(str) | |||
local arr = string.split(str , " "); | |||
return cc.p(arr[1] , arr[2]); | |||
end | |||
function cc.Color4F:toString() | |||
return tostring(self.r) .. " " .. tostring(self.g) .. " " .. tostring(self.b) .. " " .. tostring(self.a); | |||
end | |||
function cc.Color4F.fromString(str) | |||
local arr = string.split(str , " "); | |||
return cc.c4f(arr[1] , arr[2] , arr[3] , arr[4]) | |||
end | |||
function cc.Color3B:toString() | |||
return tostring(self.r) .. " " .. tostring(self.g) .. " " .. tostring(self.b); | |||
end | |||
function cc.Color3B.fromString(str) | |||
local arr = string.split(str , " "); | |||
return cc.c3b(arr[1] , arr[2] , arr[3]) | |||
end | |||
function cc.Size:toString() | |||
return tostring(self.width) .. " " .. tostring(self.height); | |||
end | |||
function cc.Size.fromString(str) | |||
local arr = string.split(str , " "); | |||
return cc.size(arr[1] , arr[2]); | |||
end | |||
function cc.Rect:toString() | |||
return tostring(self.x) .. " " .. tostring(self.y) .. " " ..tostring(self.width) .. " " .. tostring(self.height); | |||
end | |||
function cc.Rect.fromString(str) | |||
local arr = string.split(str , " "); | |||
return cc.rect(arr[1] , arr[2] , arr[3] , arr[4]); | |||
end | |||
function cc.margin(l,t,r,b) | |||
return {left = l;top = t;right = r;bottom = b}; | |||
end | |||
function cc.Margin:toString() | |||
return tostring(self.left) .. " " .. tostring(self.top) .. " " .. tostring(self.right) .. " " .. tostring(self.bottom); | |||
end | |||
function cc.Margin.fromString(str) | |||
local arr = string.split(str , " "); | |||
return cc.margin(arr[1] , arr[2] , arr[3] , arr[4]); | |||
end | |||
require("luaScript.Tools.ObjectBinder") |
@@ -0,0 +1,70 @@ | |||
-- 扩展io一些功能 | |||
function io.exists(path) | |||
local file = io.open(path, "r") | |||
if file then | |||
io.close(file) | |||
return true | |||
end | |||
return false | |||
end | |||
function io.readfile(path) | |||
local file = io.open(path, "r") | |||
if file then | |||
local content = file:read("*a") | |||
io.close(file) | |||
return content | |||
end | |||
return nil | |||
end | |||
function io.writefile(path, content, mode) | |||
mode = mode or "w+b" | |||
local file = io.open(path, mode) | |||
if file then | |||
if file:write(content) == nil then return false end | |||
io.close(file) | |||
return true | |||
else | |||
return false | |||
end | |||
end | |||
function io.pathinfo(path) | |||
local pos = string.len(path) | |||
local extpos = pos + 1 | |||
while pos > 0 do | |||
local b = string.byte(path, pos) | |||
if b == 46 then -- 46 = char "." | |||
extpos = pos | |||
elseif b == 47 then -- 47 = char "/" | |||
break | |||
end | |||
pos = pos - 1 | |||
end | |||
local dirname = string.sub(path, 1, pos) | |||
local filename = string.sub(path, pos + 1) | |||
extpos = extpos - pos | |||
local basename = string.sub(filename, 1, extpos - 1) | |||
local extname = string.sub(filename, extpos) | |||
return { | |||
dirname = dirname, | |||
filename = filename, | |||
basename = basename, | |||
extname = extname | |||
} | |||
end | |||
function io.filesize(path) | |||
local size = false | |||
local file = io.open(path, "r") | |||
if file then | |||
local current = file:seek() | |||
size = file:seek("end") | |||
file:seek("set", current) | |||
io.close(file) | |||
end | |||
return size | |||
end |
@@ -0,0 +1,64 @@ | |||
Math = math | |||
Math.E = 2.718281828459045 -- 自然数 | |||
Math.LN2 = 0.6931471805599453 -- 2的自然对数 | |||
Math.LN10 = 2.302585092994046 -- 10的自然对数 | |||
Math.LOG2E = 1.4426950408889634 -- log 2 为底的自然数 | |||
Math.LOG10E = 0.4342944819032518 -- log 10 为底的自然数 | |||
Math.PI = 3.141592653589793 -- π | |||
Math.HALF_PI = 1.57079632679489661923 -- 1/2 π | |||
Math.SQRT1_2 = 0.7071067811865476 -- 1/2的平方根 | |||
Math.SQRT2 = 1.4142135623730951 -- 2的平方根 | |||
-- p, q is on the same of line 1 | |||
function Math.isSame(line1, p, q) | |||
local dx = line1.endPoint.x - line1.startPoint.x; | |||
local dy = line1.endPoint.y - line1.startPoint.y; | |||
local dx1 = p.x - line1.startPoint.x; | |||
local dy1 = p.y - line1.startPoint.y; | |||
local dx2 = q.x - line1.endPoint.x; | |||
local dy2 = q.y - line1.endPoint.y; | |||
return (dx*dy1-dy*dx1)*(dx*dy2-dy*dx2) > 0; | |||
end | |||
-- 2 line segments (s1, s2) are intersect? | |||
function Math.isIntersect(line1, line2) | |||
local b1 = Math.isSame(line1, line2.startPoint, line2.endPoint); | |||
local b2 = Math.isSame(line2, line1.startPoint, line1.endPoint); | |||
return not b1 and not b2; | |||
end | |||
function Math.round(num) | |||
return math.floor(num + 0.5) | |||
end | |||
function Math.angle2Radian(angle) | |||
return angle*math.pi/180 | |||
end | |||
function Math.radian2Angle(radian) | |||
return radian/math.pi*180 | |||
end | |||
-- 从球面坐标系(半径,经度,纬度)转换到笛卡尔坐标系(XYZ) | |||
-- 半径,离原点的距离,一般是一个正数 | |||
-- 经度,0~2PI,0代表正前方,PI代表正后方 | |||
-- 纬度,HALF_PI代表水平位置,+PI代表底,0代表顶 | |||
function Math.SphericalToCartesian(sphericalPos) | |||
return { | |||
x = sphericalPos.x * math.cos(sphericalPos.y) * math.sin(sphericalPos.z); | |||
z = sphericalPos.x * math.sin(sphericalPos.y) * math.sin(sphericalPos.z); | |||
y = sphericalPos.x * math.cos(sphericalPos.z); | |||
} | |||
end | |||
-- 从笛卡尔坐标系(XYZ)转换到球面坐标系(半径,经度,纬度) | |||
function Math.CartesianToSpherical(cartesianPos) | |||
local r = math.sqrt(cartesianPos.x * cartesianPos.x + cartesianPos.y * cartesianPos.y + cartesianPos.z * cartesianPos.z) | |||
local lon = math.atan2(cartesianPos.z, cartesianPos.x) | |||
local lat = math.acos(cartesianPos.y / r) | |||
return cc.vec3(r, lon, lat) | |||
end |
@@ -0,0 +1,144 @@ | |||
-- 扩展string的一些功能 | |||
function string.htmlspecialchars(input) | |||
for k, v in pairs(string._htmlspecialchars_set) do | |||
input = string.gsub(input, k, v) | |||
end | |||
return input | |||
end | |||
string._htmlspecialchars_set = {} | |||
string._htmlspecialchars_set["&"] = "&" | |||
string._htmlspecialchars_set["\""] = """ | |||
string._htmlspecialchars_set["'"] = "'" | |||
string._htmlspecialchars_set["<"] = "<" | |||
string._htmlspecialchars_set[">"] = ">" | |||
function string.htmlspecialcharsDecode(input) | |||
for k, v in pairs(string._htmlspecialchars_set) do | |||
input = string.gsub(input, v, k) | |||
end | |||
return input | |||
end | |||
function string.nl2br(input) | |||
return string.gsub(input, "\n", "<br />") | |||
end | |||
function string.text2html(input) | |||
input = string.gsub(input, "\t", " ") | |||
input = string.htmlspecialchars(input) | |||
input = string.gsub(input, " ", " ") | |||
input = string.nl2br(input) | |||
return input | |||
end | |||
function string.split(str, delimiter) | |||
str = tostring(str) | |||
delimiter = tostring(delimiter) | |||
if (delimiter=='') then return false end | |||
local pos,arr = 0, {} | |||
-- for each divider found | |||
for st,sp in function() return string.find(str, delimiter, pos, true) end do | |||
table.insert(arr, string.sub(str, pos, st - 1)) | |||
pos = sp + 1 | |||
end | |||
table.insert(arr, string.sub(str, pos)) | |||
return arr | |||
end | |||
function string.ltrim(str) | |||
return string.gsub(str, "^[ \t\n\r]+", "") | |||
end | |||
function string.rtrim(str) | |||
return string.gsub(str, "[ \t\n\r]+$", "") | |||
end | |||
function string.trim(str) | |||
str = string.gsub(str, "^[ \t\n\r]+", "") | |||
return string.gsub(str, "[ \t\n\r]+$", "") | |||
end | |||
function string.ucfirst(str) | |||
return string.upper(string.sub(str, 1, 1)) .. string.sub(str, 2) | |||
end | |||
local function urlencodeChar(char) | |||
return "%" .. string.format("%02X", string.byte(char)) | |||
end | |||
function string.urlencode(str) | |||
-- convert line endings | |||
str = string.gsub(tostring(str), "\n", "\r\n") | |||
-- escape all characters but alphanumeric, '.' and '-' | |||
str = string.gsub(str, "([^%w%.%- ])", urlencodeChar) | |||
-- convert spaces to "+" symbols | |||
return string.gsub(str, " ", "+") | |||
end | |||
function string.urldecode(str) | |||
str = string.gsub (str, "+", " ") | |||
str = string.gsub (str, "%%(%x%x)", function(h) return string.char(tonum(h,16)) end) | |||
str = string.gsub (str, "\r\n", "\n") | |||
return str | |||
end | |||
function string.utf8len(str) | |||
local len = #str | |||
local left = len | |||
local cnt = 0 | |||
local arr = {0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc} | |||
while left ~= 0 do | |||
local tmp = string.byte(str, -left) | |||
local i = #arr | |||
while arr[i] do | |||
if tmp >= arr[i] then | |||
left = left - i | |||
break | |||
end | |||
i = i - 1 | |||
end | |||
cnt = cnt + 1 | |||
end | |||
return cnt | |||
end | |||
function string.formatNumberThousands(num) | |||
local formatted = tostring(tonum(num)) | |||
local k | |||
while true do | |||
formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2') | |||
if k == 0 then break end | |||
end | |||
return formatted | |||
end | |||
-- 把文件名分割成目录名和文件名 | |||
-- 返回pathName , baseName , ext | |||
function string.splitFilename(filename) | |||
local reverseFile = string.reverse(filename); | |||
local pos = string.find(reverseFile , "[/\\]"); | |||
local dotPos = string.find(reverseFile , "%."); | |||
return string.sub(filename , 1 , #filename - pos) , string.sub(filename , #filename - pos + 2) , string.sub(filename , #filename - dotPos + 2); | |||
end | |||
-- 是否是某字符串结束 | |||
function string.endsWith(filename , ends) | |||
return string.sub(filename , - #ends) == ends; | |||
end | |||
-- 是否是以字符串开头 | |||
function string.startsWith(filename , starts) | |||
return string.sub(filename , 1 , #starts) == starts; | |||
end | |||
-- 转换到lua源码格式的字符串 | |||
function string.toLuaString(str) | |||
local buffer = {"\""}; | |||
for i = 1 , string.len(str) do | |||
table.insert(buffer , [[\]] .. string.byte(str , i)); | |||
end | |||
table.insert(buffer , "\""); | |||
return table.concat(buffer); | |||
end; |
@@ -0,0 +1,354 @@ | |||
-- 这里是扩充table的一些功能 | |||
function table.nums(t) | |||
local count = 0 | |||
for k, v in pairs(t) do | |||
count = count + 1 | |||
end | |||
return count | |||
end | |||
function table.empty(t) | |||
for k, v in pairs(t) do | |||
return false; | |||
end | |||
return true; | |||
end | |||
function table.keys(t) | |||
local keys = {} | |||
for k, v in pairs(t) do | |||
keys[#keys + 1] = k | |||
end | |||
return keys | |||
end | |||
function table.values(t) | |||
local values = {} | |||
for k, v in pairs(t) do | |||
values[#values + 1] = v | |||
end | |||
return values | |||
end | |||
function table.merge(dest, src) | |||
for k, v in pairs(src) do | |||
dest[k] = v | |||
end | |||
end | |||
function table.mergeAll(src , dest) | |||
for k, v in pairs(src) do | |||
if type(v) == "table" then | |||
if not dest[k] then | |||
dest[k] = v; | |||
else | |||
table.mergeAll(v , dest[k]); | |||
end | |||
else | |||
dest[k] = v | |||
end | |||
end | |||
end | |||
function table.imerge(dest, src) | |||
for k, v in ipairs(src) do | |||
table.insert(dest , v) | |||
end | |||
end | |||
--[[-- | |||
insert list. | |||
**Usage:** | |||
local dest = {1, 2, 3} | |||
local src = {4, 5, 6} | |||
table.insertTo(dest, src) | |||
-- dest = {1, 2, 3, 4, 5, 6} | |||
dest = {1, 2, 3} | |||
table.insertTo(dest, src, 5) | |||
-- dest = {1, 2, 3, nil, 4, 5, 6} | |||
@param table dest | |||
@param table src | |||
@param table begin insert position for dest | |||
]] | |||
function table.insertTo(dest, src, begin) | |||
begin = tonumber(begin) | |||
if begin == nil then | |||
begin = #dest + 1 | |||
end | |||
local len = #src | |||
for i = 0, len - 1 do | |||
dest[i + begin] = src[i + 1] | |||
end | |||
end | |||
--[[ | |||
search target index at list. | |||
@param table list | |||
@param * target | |||
@param int from idx, default 1 | |||
@param bool useNaxN, the len use table.maxn(true) or #(false) default:false | |||
@param return index of target at list, if not return -1 | |||
]] | |||
function table.indexOf(list, target, from, useMaxN) | |||
local len = (useMaxN and #list) or table.maxn(list) | |||
if from == nil then | |||
from = 1 | |||
end | |||
for i = from, len do | |||
if list[i] == target then | |||
return i | |||
end | |||
end | |||
return -1 | |||
end | |||
function table.indexOfKey(list, key, value, from, useMaxN) | |||
local len = (useMaxN and #list) or table.maxn(list) | |||
if from == nil then | |||
from = 1 | |||
end | |||
local item = nil | |||
for i = from, len do | |||
item = list[i] | |||
if item ~= nil and item[key] == value then | |||
return i | |||
end | |||
end | |||
return -1 | |||
end | |||
function table.removeItem(t, item, removeAll) | |||
for i = #t, 1, -1 do | |||
if t[i] == item then | |||
table.remove(t, i) | |||
if not removeAll then break end | |||
end | |||
end | |||
end | |||
function table.map(t, fun) | |||
for k,v in pairs(t) do | |||
t[k] = fun(v, k) | |||
end | |||
end | |||
function table.walk(t, fun) | |||
for k,v in pairs(t) do | |||
fun(v, k) | |||
end | |||
end | |||
function table.filter(t, fun) | |||
for k,v in pairs(t) do | |||
if not fun(v, k) then | |||
t[k] = nil | |||
end | |||
end | |||
end | |||
function table.find(t, item) | |||
return table.keyOfItem(t, item) ~= nil | |||
end | |||
function table.unique(t) | |||
local r = {} | |||
local n = {} | |||
for i = #t, 1, -1 do | |||
local v = t[i] | |||
if not r[v] then | |||
r[v] = true | |||
n[#n + 1] = v | |||
end | |||
end | |||
return n | |||
end | |||
function table.keyOfItem(t, item) | |||
for k,v in pairs(t) do | |||
if v == item then return k end | |||
end | |||
return nil | |||
end | |||
function table.valueOfItem(t, item) | |||
for k,v in pairs(t) do | |||
if v == item then return v end | |||
end | |||
return nil | |||
end | |||
-- 把表转换成类似这种格式的字符串{a='b';};,字符串用二进制格式表示"\01\02"之类 | |||
function table.toString(t) | |||
local tableString = vardump(t , ""); | |||
return tableString:sub(8); | |||
end | |||
-- 把表转换成类似这种格式的字符串{a='b';};,字符串用可见文本形式表示 | |||
function table.tostring(t) | |||
if not t then | |||
return "nil" | |||
end | |||
local oldFunc = string.toLuaString; | |||
string.toLuaString = tostring; | |||
local tableString = vardump(t , ""); | |||
string.toLuaString = oldFunc | |||
return tableString:sub(8); | |||
end | |||
-- 把表转换成类似这种格式的字符串return {a='b';}; | |||
function table.saveString(t) | |||
return "return " .. table.toString(t); | |||
end | |||
-- 从字符串中载入一个表 | |||
function table.loadString(tableString) | |||
local data , err = loadstring(tableString); | |||
if data == nil then | |||
print("table.loadString()", tostring(tableString)) | |||
--error(err); | |||
uploadLogs(GAME_ERROR_TYPE.TABLELOADSTRING) | |||
return nil | |||
else | |||
return data(); | |||
end | |||
end | |||
-- 将一个table数据保存到本地文件 | |||
function table.saveToLocFile(t, filename) | |||
if not t or not filename then | |||
return | |||
end | |||
local tableString = table.saveString(t) | |||
saveStringToFile(tableString, filename) | |||
end | |||
-- 从本地文件读取一个table数据 | |||
function table.loadFromLocFile(filename) | |||
if not filename then | |||
return | |||
end | |||
local tableString = loadStringFromFile(filename) | |||
if not tableString then | |||
return nil | |||
end | |||
return table.loadString(tableString) | |||
end | |||
-- 把表保存到文件中 | |||
function table.saveFile(t , filename) | |||
local file , err = io.open(filename , "w"); | |||
if file == nil then | |||
error(err); | |||
return; | |||
end | |||
file:write("return ") | |||
file:write(table.toString(t)); | |||
file:close(); | |||
end | |||
if EditorMode then | |||
-- 从文件中载入一个表 | |||
function table.loadFile(filename) | |||
local n,r = loadLuaFile(filename); | |||
if n == nil then | |||
--error("载入文件" .. tostring(filename) .. "时出错" .. r); | |||
return nil | |||
end | |||
return n(); | |||
end | |||
else | |||
-- 从文件中载入一个表 | |||
local tableCache = {}; | |||
function table.loadFile(filename) | |||
local cache = tableCache[filename]; | |||
if cache then | |||
return cache; | |||
end | |||
print("table.loadFile:" .. filename); | |||
TimeSpan:enterSpan("table.loadFile:" .. filename); | |||
local n,r = loadLuaFile(filename); | |||
if n == nil then | |||
--error("载入文件" .. tostring(filename) .. "时出错" .. r); | |||
return nil | |||
end | |||
TimeSpan:enterSpan("runTable"); | |||
cache = n(); | |||
TimeSpan:leaveSpan(); | |||
tableCache[filename] = cache; | |||
TimeSpan:leaveSpan(); | |||
return cache; | |||
end | |||
end | |||
-- 兼容版本 | |||
if not table.getn then | |||
function table.getn(t) | |||
return #t; | |||
end | |||
end | |||
local rawpairs = pairs | |||
------------------------------------------- | |||
-- 可以按指定顺序遍历的map迭代器 | |||
-- @param tbl 要迭代的表 | |||
-- @param func 比较函数 | |||
-- @example | |||
-- for k,v in pairs(tbl,defaultComp) do print(k,v) end | |||
function table.sortPairs(tbl, func) | |||
if func == nil then | |||
return rawpairs(tbl) | |||
end | |||
-- 为tbl创建一个对key排序的数组 | |||
-- 自己实现插入排序,table.sort遇到nil时会失效 | |||
local ary = {} | |||
for key in rawpairs(tbl) do | |||
ary[#ary+1] = key | |||
end | |||
table.sort(ary,func); | |||
-- 定义并返回迭代器 | |||
local i = 0 | |||
local iter = function () | |||
i = i + 1 | |||
if ary[i] == nil then | |||
return nil | |||
else | |||
return ary[i], tbl[ary[i]] | |||
end | |||
end | |||
return iter | |||
end | |||
-------------------------------- | |||
-- 通用比较器(Comparator) | |||
-- @return 对比结果 | |||
function table.defaultSort( op1, op2 ) | |||
local type1, type2 = type(op1), type(op2) | |||
local num1, num2 = tonumber(op1), tonumber(op2) | |||
if ( num1 ~= nil) and (num2 ~= nil) then | |||
return num1 < num2 | |||
elseif type1 ~= type2 then | |||
return type1 < type2 | |||
elseif type1 == "string" then | |||
return op1 < op2 | |||
elseif type1 == "boolean" then | |||
return op1 | |||
-- 以上处理: number, string, boolean | |||
else -- 处理剩下的: function, table, thread, userdata | |||
return tostring(op1) < tostring(op2) -- tostring后比较字符串 | |||
end | |||
end |
@@ -0,0 +1,53 @@ | |||
-- 所有聊天相关的配置 | |||
local ChatDef = {} | |||
-- 聊天类型 | |||
-- //类型 1: 表情 2: 语音 3:聊天 | |||
ChatDef.MessageType = | |||
{ | |||
Face = 1, -- 表情 | |||
Voice = 2, -- 录音 | |||
Message = 3, -- 快捷语 | |||
Prop = 4, -- 道具 | |||
Chat = 5, -- 聊天 服务器类型还是3 | |||
} | |||
ChatDef.TimeInterval = | |||
{ | |||
[ChatDef.MessageType.Face] = 3, -- 表情 | |||
[ChatDef.MessageType.Voice] = 5, -- 录音 | |||
[ChatDef.MessageType.Message] = 5, -- 快捷语 | |||
[ChatDef.MessageType.Prop] = 10, -- 道具 | |||
[ChatDef.MessageType.Chat] = 3, -- 聊天 | |||
} | |||
-- 录音动画/快捷语的方向 | |||
ChatDef.Direction = | |||
{ | |||
Left = 1, -- 头像在左,动画在右 | |||
Right = 2, -- 头像在右,动画在左 | |||
} | |||
-- 表情相关的文件 | |||
ChatDef.FaceBtnFile = "res/ui/zy_tongyong/zy_face/Face.plist" | |||
ChatDef.FaceConfigs = | |||
{ | |||
[1] = {oggLocal="res/sound/%s/common_%s_emoj_1.ogg",oggStandard="res/sound/%s/common_%s_emoj_1.ogg", btnPng = "face_j_1001.png", aniFile = "res/ui/zy_tongyong/zy_face/face1_anims_i6p.plist", aniString = "face1_%d.png", frameNum = 10}, | |||
[2] = {oggLocal="res/sound/%s/common_%s_emoj_2.ogg",oggStandard="res/sound/%s/common_%s_emoj_2.ogg", btnPng = "face_j_1002.png", aniFile = "res/ui/zy_tongyong/zy_face/face2_anims_i6p.plist", aniString = "face2_%d.png", frameNum = 10}, | |||
[3] = {oggLocal="res/sound/%s/common_%s_emoj_3.ogg",oggStandard="res/sound/%s/common_%s_emoj_3.ogg", btnPng = "face_j_1003.png", aniFile = "res/ui/zy_tongyong/zy_face/face3_anims_i6p.plist", aniString = "face3_%d.png", frameNum = 10}, | |||
[4] = {oggLocal="res/sound/%s/common_%s_emoj_4.ogg",oggStandard="res/sound/%s/common_%s_emoj_4.ogg", btnPng = "face_j_1004.png", aniFile = "res/ui/zy_tongyong/zy_face/face4_anims_i6p.plist", aniString = "face4_%d.png", frameNum = 10}, | |||
[5] = {oggLocal="res/sound/%s/common_%s_emoj_5.ogg",oggStandard="res/sound/%s/common_%s_emoj_5.ogg", btnPng = "face_j_1005.png", aniFile = "res/ui/zy_tongyong/zy_face/face5_anims_i6p.plist", aniString = "face5_%d.png", frameNum = 10}, | |||
[6] = {oggLocal="res/sound/%s/common_%s_emoj_6.ogg",oggStandard="res/sound/%s/common_%s_emoj_6.ogg", btnPng = "face_j_1006.png", aniFile = "res/ui/zy_tongyong/zy_face/face6_anims_i6p.plist", aniString = "face6_%d.png", frameNum = 10}, | |||
[7] = {oggLocal="res/sound/%s/common_%s_emoj_7.ogg",oggStandard="res/sound/%s/common_%s_emoj_7.ogg", btnPng = "face_j_1007.png", aniFile = "res/ui/zy_tongyong/zy_face/face7_anims_i6p.plist", aniString = "face7_%d.png", frameNum = 10}, | |||
[8] = {oggLocal="res/sound/%s/common_%s_emoj_8.ogg",oggStandard="res/sound/%s/common_%s_emoj_8.ogg", btnPng = "face_j_1008.png", aniFile = "res/ui/zy_tongyong/zy_face/face8_anims_i6p.plist", aniString = "face8_%d.png", frameNum = 10}, | |||
[9] = {oggLocal="res/sound/%s/common_%s_emoj_9.ogg",oggStandard="res/sound/%s/common_%s_emoj_9.ogg", btnPng = "face_j_1009.png", aniFile = "res/ui/zy_tongyong/zy_face/face9_anims_i6p.plist", aniString = "face9_%d.png", frameNum = 10}, | |||
[10] = {oggLocal="res/sound/%s/common_%s_emoj_10.ogg",oggStandard="res/sound/%s/common_%s_emoj_10.ogg", btnPng = "face_j_1010.png", aniFile = "res/ui/zy_tongyong/zy_face/face10_anims_i6p.plist", aniString = "face10_%d.png", frameNum = 10}, | |||
[11] = {oggLocal="res/sound/%s/common_%s_emoj_11.ogg",oggStandard="res/sound/%s/common_%s_emoj_11.ogg", btnPng = "face_j_1011.png", aniFile = "res/ui/zy_tongyong/zy_face/face11_anims_i6p.plist", aniString = "face11_%d.png", frameNum = 10}, | |||
[12] = {oggLocal="res/sound/%s/common_%s_emoj_12.ogg",oggStandard="res/sound/%s/common_%s_emoj_12.ogg", btnPng = "face_j_1012.png", aniFile = "res/ui/zy_tongyong/zy_face/face12_anims_i6p.plist", aniString = "face12_%d.png", frameNum = 10}, | |||
} | |||
return ChatDef | |||
@@ -0,0 +1,214 @@ | |||
-- 游戏逻辑相关的全局函数 | |||
local BGMusicPlayer = require("luaScript.Tools.MusicPlayer")(); | |||
--背景音乐的通用接口 | |||
function playBGMusic(key, musicFileName) | |||
playConfig = | |||
{ | |||
-- 唯一的名字,如果正在播的是这个名字,就忽略 | |||
Name = key; | |||
-- 需要播放的声音列表,会从中随机一首 | |||
Files = {musicFileName}; | |||
-- 播放几率,[0-100] | |||
Rate = 100; | |||
-- 每批的间隔 | |||
IntervalMin = 0; | |||
IntervalMax = 0; | |||
-- 一批播放多少次 | |||
PlayCountMin = 1; | |||
PlayCountMax = 1; | |||
-- 循环多少批,0表示无限循环 | |||
LoopCount = 0; | |||
-- 延迟几秒才开始播放 | |||
DelayTime = 0; | |||
-- 声音停止时的淡出时间(秒) | |||
FadeOut = 0; | |||
} | |||
BGMusicPlayer.playBGMusic(playConfig); | |||
end | |||
function stopBGMusic() | |||
return BGMusicPlayer.stopBGMusic(); | |||
end | |||
--音效的通用接口 | |||
function playVoice(voiceFileName) | |||
local soundVolume = app.systemSetting.info.soundVolume | |||
local sound = cc.AudioController:getInstance():playSound(voiceFileName, false); | |||
if sound then | |||
sound:setGain(soundVolume) | |||
end | |||
return sound | |||
end | |||
function stopVoice(sound) | |||
if sound then | |||
cc.AudioController:getInstance():stopSound(sound) | |||
end | |||
end | |||
-------------------- MUSIC --------------------------- | |||
function playMusicLogin() | |||
playBGMusic("BG_Login", "res/sound/bg_login.ogg") | |||
end | |||
function playMusicHall() | |||
playBGMusic("BG_Hall", "res/sound/bg_hall.ogg") | |||
end | |||
function playMusicRoom(index) | |||
if index == 0 then | |||
playBGMusic("BG_Room", "res/sound/room/bgmusic.ogg") | |||
else | |||
playBGMusic("BG_Room", "res/sound/room/bgm.ogg") | |||
end | |||
end | |||
-------------------- SOUND --------------------------- | |||
-- 播放发牌的音效 | |||
function playVoiceGiveCard() | |||
playVoice("res/sound/g_flop.ogg") | |||
end | |||
--播放行为操作音效 | |||
function playVoiceNiuX(NiuX,nUserId) | |||
if not NiuX then | |||
return | |||
end | |||
local memberInfo = app.room.roomInfo.memberList[nUserId] | |||
if memberInfo then | |||
local userInfo = json.decode(memberInfo.userInfo) | |||
if not userInfo then | |||
return | |||
end | |||
--男1女2,默认是男生 | |||
local sexNum = userInfo.sex or 1 | |||
--因为女生用的资源是0 | |||
if tonumber(sexNum) == 2 then | |||
sexNum = 0 | |||
end | |||
local sex = tostring(sexNum) | |||
local voiceName = "" | |||
if tonumber(sexNum) == 1 then | |||
voiceName = string.format("res/sound/room/gg_ogg/f0_nn%d.ogg", NiuX) | |||
else | |||
--女生或者人妖(可能性别保密)进这里播放 | |||
voiceName = string.format("res/sound/room/mm_ogg/f1_nn%d.ogg", NiuX) | |||
end | |||
playVoice(voiceName) | |||
end | |||
end | |||
--播放不抢庄操作音效 | |||
function playVoiceBuQiang(nUserId) | |||
local memberInfo = app.room.roomInfo.memberList[nUserId] | |||
if memberInfo then | |||
local userInfo = json.decode(memberInfo.userInfo) | |||
if not userInfo then | |||
return | |||
end | |||
--男1女2,默认是男生 | |||
local sexNum = userInfo.sex or 1 | |||
--因为女生用的资源是0 | |||
if tonumber(sexNum) == 2 then | |||
sexNum = 0 | |||
end | |||
local sex = tostring(sexNum) | |||
local voiceName = "" | |||
if tonumber(sexNum) == 1 then | |||
voiceName = "res/sound/room/buqiang_0.ogg" | |||
else | |||
--女生或者其他 | |||
voiceName = "res/sound/room/buqiang_1.ogg" | |||
end | |||
playVoice(voiceName) | |||
end | |||
end | |||
--播放抢庄操作音效 | |||
function playVoiceQiang(nUserId) | |||
local memberInfo = app.room.roomInfo.memberList[nUserId] | |||
if memberInfo then | |||
local userInfo = json.decode(memberInfo.userInfo) | |||
if not userInfo then | |||
return | |||
end | |||
--男1女2,默认是男生 | |||
local sexNum = userInfo.sex or 1 | |||
--因为女生用的资源是0 | |||
if tonumber(sexNum) == 2 then | |||
sexNum = 0 | |||
end | |||
local sex = tostring(sexNum) | |||
local voiceName = "" | |||
if tonumber(sexNum) == 1 then | |||
voiceName = "res/sound/room/qiangzhuang_0.ogg" | |||
else | |||
--女生或者其他 | |||
voiceName = "res/sound/room/qiangzhuang_1.ogg" | |||
end | |||
playVoice(voiceName) | |||
end | |||
end | |||
--播放按钮点击音效 | |||
function playBtnEffect() | |||
playVoice("res/sound/click.ogg") | |||
end | |||
--播放按钮关闭音效 | |||
function playBtnCloseEffect() | |||
playVoice("res/sound/effect_return.ogg") | |||
end | |||
--播放标签页点击音效 | |||
function playBtnTagEffect() | |||
playVoice("res/sound/effect_biaoqian.ogg") | |||
end | |||
--播放金币飞 | |||
function playOneCoinEffect() | |||
playVoice("res/sound/room/coin_big.ogg") | |||
end | |||
--播放下注 | |||
function playCoinsEffect() | |||
playVoice("res/sound/room/chips_to_table.ogg") | |||
end | |||
--播放下注 | |||
function playCoinsFlyEffect() | |||
playVoice("res/sound/room/coins_fly.ogg") | |||
end | |||
--播放抢庄家音效 | |||
function playVoiceRootBanker() | |||
playVoice("res/sound/room/random_banker_lianxu.ogg") | |||
end | |||
--播放成功失败音效 | |||
function playEndVoice(cardFileName) | |||
local voiceName = string.format("res/sound/room/%s.ogg", cardFileName) | |||
playVoice(voiceName) | |||
end | |||
--播放闹钟 | |||
function playClockVoice() | |||
local voiceName = "res/sound/time_over.ogg" | |||
playVoice(voiceName) | |||
end |
@@ -0,0 +1,392 @@ | |||
-- 全局的游戏数据类型定义 | |||
-- UI显示顺序的Order | |||
UIZOrder = | |||
{ | |||
-- showTooltip | |||
TipsOrder = 20000, | |||
-- 重启或退出对话框 | |||
ExitOrder = 15000, | |||
-- 最上面是网络等待蒙版 | |||
NetWaitOrder = 10000, | |||
-- 系统通知 | |||
SystemNotify = 7000, | |||
-- 横幅 | |||
DropNotify = 6000, | |||
-- 每日签到 | |||
SignOrder = 5500, | |||
-- 其次是新手引导蒙版 | |||
GuideOrder = 5000, | |||
-- 再下面是通用界面淡入淡出蒙版 | |||
FadeOrder= 2000, | |||
-- 充值界面 | |||
Recharge = 1000, | |||
-- 主界面 | |||
MainLayer = -1, | |||
} | |||
-- 表情相关的文件 | |||
Face_Btn_File = "res/ui/zy_tongyong/zy_face/Face.plist" | |||
Face_Def = | |||
{ | |||
[1] = { btnPng = "face_j_1001.png", aniFile = "res/ui/zy_tongyong/zy_face/face1_anims_i6p.plist", aniString = "face1_%d.png", frameNum = 10}, | |||
[2] = { btnPng = "face_j_1002.png", aniFile = "res/ui/zy_tongyong/zy_face/face2_anims_i6p.plist", aniString = "face2_%d.png", frameNum = 10}, | |||
[3] = { btnPng = "face_j_1003.png", aniFile = "res/ui/zy_tongyong/zy_face/face3_anims_i6p.plist", aniString = "face3_%d.png", frameNum = 10}, | |||
[4] = { btnPng = "face_j_1004.png", aniFile = "res/ui/zy_tongyong/zy_face/face4_anims_i6p.plist", aniString = "face4_%d.png", frameNum = 10}, | |||
[5] = { btnPng = "face_j_1005.png", aniFile = "res/ui/zy_tongyong/zy_face/face5_anims_i6p.plist", aniString = "face5_%d.png", frameNum = 10}, | |||
[6] = { btnPng = "face_j_1006.png", aniFile = "res/ui/zy_tongyong/zy_face/face6_anims_i6p.plist", aniString = "face6_%d.png", frameNum = 10}, | |||
[7] = { btnPng = "face_j_1007.png", aniFile = "res/ui/zy_tongyong/zy_face/face7_anims_i6p.plist", aniString = "face7_%d.png", frameNum = 10}, | |||
[8] = { btnPng = "face_j_1008.png", aniFile = "res/ui/zy_tongyong/zy_face/face8_anims_i6p.plist", aniString = "face8_%d.png", frameNum = 10}, | |||
[9] = { btnPng = "face_j_1009.png", aniFile = "res/ui/zy_tongyong/zy_face/face9_anims_i6p.plist", aniString = "face9_%d.png", frameNum = 10}, | |||
[10] = { btnPng = "face_j_1010.png", aniFile = "res/ui/zy_tongyong/zy_face/face10_anims_i6p.plist", aniString = "face10_%d.png", frameNum = 10}, | |||
[11] = { btnPng = "face_j_1011.png", aniFile = "res/ui/zy_tongyong/zy_face/face11_anims_i6p.plist", aniString = "face11_%d.png", frameNum = 10}, | |||
[12] = { btnPng = "face_j_1012.png", aniFile = "res/ui/zy_tongyong/zy_face/face12_anims_i6p.plist", aniString = "face12_%d.png", frameNum = 10}, | |||
} | |||
-- 游戏道具 | |||
Prop_Btn_File = "res/ui/zy_tongyong/zy_prop/zy_prop.plist" | |||
GameProp = | |||
{ | |||
[1] = {icon = "userInfo_prop1.png", image = "res/ui/zy_tongyong/zy_prop/item1/item1_fly-i6p.png", plistFile = "res/ui/zy_tongyong/zy_prop/item1/item1_anims_i6p.plist", frameName = "item1_%d.png", frameNum = 19}, | |||
[2] = {icon = "userInfo_prop2.png", image = "res/ui/zy_tongyong/zy_prop/item2/item2_fly-i6p.png", plistFile = "res/ui/zy_tongyong/zy_prop/item2/item2_anims_i6p.plist", frameName = "item2_%d.png", frameNum = 28}, | |||
[3] = {icon = "userInfo_prop3.png", image = "res/ui/zy_tongyong/zy_prop/item3/item3_fly-i6p.png", plistFile = "res/ui/zy_tongyong/zy_prop/item3/item3_anims_i6p.plist", frameName = "item3_%d.png", frameNum = 21}, | |||
[4] = {icon = "userInfo_prop4.png", image = "res/ui/zy_tongyong/zy_prop/item4/item4_fly-i6p.png", plistFile = "res/ui/zy_tongyong/zy_prop/item4/item4_anims_i6p.plist", frameName = "item4_%d.png", frameNum = 29}, | |||
[5] = {icon = "userInfo_prop5.png", image = "res/ui/zy_tongyong/zy_prop/item5/item5_fly-i6p.png", plistFile = "res/ui/zy_tongyong/zy_prop/item5/item5_anims_i6p.plist", frameName = "item5_%d.png", frameNum = 19}, | |||
[6] = {icon = "userInfo_prop6.png", image = "res/ui/zy_tongyong/zy_prop/item6/item6_fly-i6p.png", plistFile = "res/ui/zy_tongyong/zy_prop/item6/item6_anims_i6p.plist", frameName = "item6_%d.png", frameNum = 28}, | |||
[7] = {icon = "userInfo_prop7.png", image = "res/ui/zy_tongyong/zy_prop/item7/item7_fly-i6p.png", plistFile = "res/ui/zy_tongyong/zy_prop/item7/item7_anims_i6p.plist", frameName = "item7_%d.png", frameNum = 30}, | |||
[8] = {icon = "userInfo_prop8.png", image = "res/ui/zy_tongyong/zy_prop/item8/item8_fly-i6p.png", plistFile = "res/ui/zy_tongyong/zy_prop/item8/item8_anims_i6p.plist", frameName = "item8_%d.png", frameNum = 13}, | |||
[9] = {icon = "userInfo_prop9.png", image = "res/ui/zy_tongyong/zy_prop/item9/item9_fly-i6p.png", plistFile = "res/ui/zy_tongyong/zy_prop/item9/item9_anims_i6p.plist", frameName = "item9_%d.png", frameNum = 33}, | |||
[10] = {icon = "userInfo_prop10.png", image = "res/ui/zy_tongyong/zy_prop/item10/item10_fly-i6p.png", plistFile = "res/ui/zy_tongyong/zy_prop/item10/item10_anims_i6p.plist", frameName = "item10_%d.png", frameNum = 4}, | |||
} | |||
-- 道具顺序 | |||
GamePropSort = {10,9,4,2,3,5,8,6,1,7} | |||
--支付方式 | |||
PayType = | |||
{ | |||
Apple = 1, -- 苹果支付 | |||
PAY_TYPE_WEXIN = 2, -- 微信支付 | |||
PAY_TYPE_H5 = 3, -- h5支付 | |||
PAY_TYPE_WEXIN_SHARE = 10, -- 微信分享支付 | |||
PAY_TYPE_HYB = 11, -- 汇元宝 | |||
PAY_TYPE_ALIPAY = 13, -- 支付宝 | |||
} | |||
-- 玩家的 GPS 状态 | |||
GpsStatus = | |||
{ | |||
close = 0, --// 未开启 | |||
undeal = 1, --// 未处理 | |||
enable = 2, --// 允许 | |||
disEnable = 3, --// 拒绝的 | |||
unkown = 99, --// 未知的 | |||
} | |||
GpsStatusString = | |||
{ | |||
[GpsStatus.close] = "GPS未开启", --// 未开启 | |||
[GpsStatus.undeal] = "GPS未授权", --// 未处理 | |||
[GpsStatus.enable] = "GPS已开启", --// 允许 | |||
[GpsStatus.disEnable] = "GPS已拒绝", --// 拒绝的 | |||
[GpsStatus.unkown] = "GPS状态未知", --// 未知的 | |||
} | |||
-- GPS状态的提示颜色 | |||
GpsStatusColor = | |||
{ | |||
[GpsStatus.close] = cc.c3b(219,56,35), --// 未开启 | |||
[GpsStatus.undeal] = cc.c3b(233, 089, 083), --// 未处理 | |||
[GpsStatus.enable] = cc.c3b(113, 184, 109), --// 允许 | |||
[GpsStatus.disEnable] = cc.c3b(233, 089, 083), --// 拒绝的 | |||
[GpsStatus.unkown] = cc.c3b(255, 255, 255), --// 拒绝的 | |||
} | |||
-- GPS距离的提示颜色 | |||
GpsDistanceColor = | |||
{ | |||
["safe"] = cc.c3b(040, 255, 082), --大于安全距离 | |||
["danger"] = cc.c3b(255, 032, 042), --小于安全距离 | |||
} | |||
-- GPS界面的默认颜色 | |||
GpsDefaultColor = cc.c3b(255, 255, 255) | |||
-- 大厅需要预加载的ui文件 | |||
UI_IN_HALL = | |||
{ | |||
-- "res/ui/ui_dating/ui_activity_main.ui", | |||
-- "res/ui/ui_dating/ui_bangzhu.ui", | |||
-- "res/ui/ui_dating/ui_chongzhi.ui", | |||
-- "res/ui/ui_dating/ui_chongzhi_xuanze.ui", | |||
-- "res/ui/ui_dating/ui_chuangjian.ui", | |||
-- "res/ui/ui_dating/ui_dailizhaomu.ui", | |||
-- "res/ui/ui_dating/ui_dating.ui", | |||
-- "res/ui/ui_dating/ui_dating_icon.ui", | |||
-- "res/ui/ui_dating/ui_duihuan.ui", | |||
-- "res/ui/ui_dating/ui_duihuan_tiao.ui", | |||
-- "res/ui/ui_dating/ui_gonggao_tiao.ui", | |||
-- "res/ui/ui_dating/ui_huodong.ui", | |||
-- "res/ui/ui_dating/ui_InviteCode.ui", | |||
-- "res/ui/ui_dating/ui_jiarufangjian.ui", | |||
-- "res/ui/ui_dating/ui_shezhi.ui", | |||
-- "res/ui/ui_dating/ui_shiming.ui", | |||
-- "res/ui/ui_dating/ui_shuzijianpan.ui", | |||
-- "res/ui/ui_dating/ui_xiazai.ui", | |||
-- "res/ui/ui_club/ui_club_main.ui", | |||
} | |||
--茶馆需要预加载的ui文件 | |||
UI_IN_CLUB = | |||
{ | |||
-- "res/ui/ui_club/ui_club_zhanji.ui", | |||
-- "res/ui/ui_club/ui_club_player_list.ui", | |||
-- "res/ui/ui_club/ui_club_baojian.ui", | |||
-- "res/ui/ui_club/ui_club_message.ui", | |||
} | |||
--游戏对应人数 | |||
GAME_CONST = | |||
{ | |||
CHENZHOU_GAME_CONST_PLAYER = 3,--郴州字牌玩家数量 | |||
LIUHUQIANG_GAME_CONST_PLAYER = 4,--六胡抢玩家数量 | |||
} | |||
--茶馆设置状态操作 | |||
GAME_CLUB_SET_STATE = | |||
{ | |||
Club_status = 1, --状态操作茶馆(管理员专属) | |||
Join_set = 2, --加入设置(管理员专属) | |||
Change_club_name= 3, --修改昵称(管理员专属) | |||
Change_privacy = 4, --隐私昵称(管理员专属) | |||
Forbid_share = 6, --屏蔽微信分享(管理员专属) | |||
Change_Mode = 7, --房间模式修改room_mode $value 1多玩法模式, 0包间模式; | |||
Set_win_socre = 8, --大家赢分数统计 | |||
Quit_set = 9, --退群申请设置 (创始人)is_exitapply $value 1需要申请, 0无需申请; 无广播 | |||
Math_Switch = 13, --比赛场开关 | |||
} | |||
--茶馆战绩类型 | |||
ClUB_ZHANJI_TYPE = | |||
{ | |||
Club = 1, -- 茶馆战绩 | |||
Mine = 2, -- 我的战绩 | |||
ZhanjiTongji = 3,-- 茶馆战绩统计 | |||
} | |||
--茶馆默认桌子数量 | |||
GAME_CLUB_TABLE_NUM = | |||
{ | |||
club_normal_num = 20, | |||
} | |||
GAME_EVENT = { | |||
DISSMISS_UPDATE_STATUS = "DISSMISS_UPDATE_STATUS", | |||
DISSMISS_CLOSE = "DISSMISS_CLOSE", | |||
RECHARGE_RESULT = "RECHARGE_RESULT", | |||
RECHARGE_CLOSE = "RECHARGE_CLOSE", | |||
UPDATE_WEB_GAME = "UPDATE_WEB_GAME", | |||
EXCHANGE_RESULT = "EXCHANGE_RESULT", | |||
ACTIVITY_CLOSE = "ACTIVITY_CLOSE", | |||
--更新GPS用户数据 | |||
GPS_UPDATE_USER_INFO = "GPS_UPDATE_USER_INFO", | |||
--聊天界面 | |||
CHAT_PRSPONSE = "CHAT_PRSPONSE", --收到聊天数据 | |||
CHAT_GET_RECORED = "CHAT_GET_RECORED", --获取聊天记录 | |||
CHAT_GET_RECORED_RESP = "CHAT_GET_RECORED_RESP", --获取聊天记录回调 | |||
CHAT_VOICE_RESP = "CHAT_VOICE_RESP", --收到语音消息 | |||
CHAT_PLAY_VOICE = "CHAT_PLAY_VOICE",--播放语音播放 | |||
CHAT_STOP_VOICE = "CHAT_STOP_VOICE",--停止语音播放 | |||
CHAT_REPLAY_VOICE = "CHAT_REPLAY_VOICE",--重复语音播放 | |||
--俱乐部 | |||
CLUB_MAIN_CLOSE = "CLUB_MAIN_CLOSE", | |||
CLUB_LIST = "CLUB_LIST", | |||
CLUB_TABLE = "CLUB_TABLE", | |||
CLUB_UPDATE_TABLE = "CLUB_UPDATE_TABLE", --刷新单个桌子 | |||
CLUB_TABLE_NUM = "CLUB_TABLE_NUM", --刷新桌子数量 | |||
CLUB_GAME_RULE = "CLUB_GAME_RULE", | |||
CLUB_CHANGE_RULE = "CLUB_CHANGE_RULE", --修改玩法 | |||
CLUB_CHANGE_RULE_PUSH = "CLUB_CHANGE_RULE_PUSH", --玩法修改推送 | |||
CLUB_CHANGE_BAO_JIAN = "CLUB_CHANGE_BAO_JIAN", --切换包间 | |||
CLUB_CHANGE_BAO_JIAN_NAME = "CLUB_CHANGE_BAO_JIAN_NAME", --切换包间 | |||
CLUB_JIE_SAN = "CLUB_JIE_SAN", --茶馆解散 | |||
CLUB_JOIN = "CLUB_JOIN", --茶馆加入 | |||
CLUB_SET = "CLUB_SET", --茶馆设置 | |||
CLUB_CHANGE_PUSH = "CLUB_CHANGE_PUSH", --茶馆修改推送 (除去桌子外的数据) | |||
CLUB_MESSAGE = "CLUB_MESSAGE", | |||
CLUB_MESSAGE_C0PARTNER = "CLUB_MESSAGE_C0PARTNER",--合伙人申请 | |||
CLUB_MESSAGE_REAWRD = "CLUB_MESSAGE_REAWRD", --领取奖励 | |||
CLUB_MESSAGE_CHANGED = "CLUB_MESSAGE_CHANGED", -- 消息有变动 | |||
CLUB_PLAYER_LIST = "CLUB_PLAYER_LIST", | |||
CLUB_PLAYER_SEARCH = "CLUB_PLAYER_SEARCH", | |||
CLUB_INVITE_PLAYER_LIST = "CLUB_INVITE_PLAYER_LIST", --邀请的成员列表 | |||
CLUB_PLAYER_BAN_LIST = "CLUB_PLAYER_BAN_LIST", --禁止同桌列表 | |||
CLUB_PLAYER_BAN_SET = "CLUB_PLAYER_BAN_SET", --设置禁止同桌 | |||
CLUB_PLAYER_ADD = "CLUB_PLAYER_ADD", | |||
CLUB_PLAYER_BAN_ALL_LIST = "CLUB_PLAYER_BAN_ALL_LIST", --查看禁止列表 | |||
CLUB_BACK_ROOM = "CLUB_BACK_ROOM", --茶馆回到房间界面 | |||
CLUB_NOTICE = "CLUB_NOTICE", --茶馆公告 | |||
CLUB_ACTIVITY_LIST = "CLUB_ACTIVITY_LIST", --活动列表 | |||
CLUB_CREATE_ERR = "CLUB_CREATE_ERR",--创建错误 | |||
CLUB_CREATE_SUCCESS = "CLUB_CREATE_SUCCESS", -- 创建亲友圈成功 | |||
CLUB_INVITE = "CLUB_INVITE", --邀请成员 | |||
CLUB_CHANGE_ROLE = "CLUB_CHANGE_ROLE", --成员列表权限改变 | |||
CLUB_MEMBER_SET_SUCCESS = "MemberSetSuccess", -- 成员属性修改成功 | |||
GetCopartnerSub = "GetCopartnerSub",--获取所有合伙人对应的下线 | |||
CopartnerSetup = "CopartnerSetup",--给合伙人设置下线 | |||
GetCopartnerStat = "GetCopartnerStat",--合伙人(所有合伙人&统计) | |||
GetCopartnerDetail = "GetCopartnerDetail",--合伙人贡献详情 | |||
CLUB_CHANGE_BG = "CLUB_CHANGE_BG", --亲友圈更换背景 | |||
CLUB_SET_MATCH = "CLUB_SET_MATCH", --俱乐部设置比赛 | |||
CLUB_SET_TABLE_STYLE = "CLUB_SET_TABLE_STYLE", -- 更换亲友圈桌子颜色 | |||
CLUB_RED_FLOWER_RECORD = "CLUB_RED_FLOWER_RECORD", --俱乐部红花记录 | |||
CLUB_UPDATE_RED_FLOWER = "CLUB_UPDATE_RED_FLOWER", --俱乐部红花更新 | |||
EVENT_CHANGE_ADDRESS = "EVENT_CHANGE_ADDRESS", -- 大厅修改自己所在地区 | |||
CLUB_CANCEL_COPARTNER_NOTICE = "CLUB_CANCEL_COPARTNER_NOTICE", --取消合伙人通知 | |||
CLUB_CANCEL_COPARTNER = "CLUB_CANCEL_COPARTNER", --取消合伙人操作 | |||
CLUB_CANCEL_COPARTNER_TIP = "CLUB_CANCEL_COPARTNER_TIP", --取消合伙人操作后的提示 | |||
NOTICE_REQUEST_PLAYER_LIST = "NOTICE_REQUEST_PLAYER_LIST", --分布式请求成员列表数据 | |||
UPDATE_COPARTNER_RATDIO = "UPDATE_COPARTNER_RATDIO", --更新一二级合伙人比例 | |||
CLUB_IMPORT_MBMBER = "CLUB_IMPORT_MBMBER", --俱乐部导入 | |||
CLUB_ACTIVE_GAME = "CLUB_ACTIVE_GAME", --俱乐部激活游戏 | |||
CLUB_ACTIVE_RULE = "CLUB_ACTIVE_RULECLUB_ACTIVE_RULE", --俱乐部激活玩法 | |||
CLUB_ROOM_LIST_UPDATE = "CLUB_ROOM_LIST_UPDATE", --俱乐部房间刷新 | |||
CLUB_GPS_DISTANCE = "CLUB_GPS_DISTANCE", --俱乐部俱乐部距离刷新 | |||
-- | |||
CLUB_SET_COPARTNER_ONE_FAILE = "CLUB_SET_COPARTNER_ONE_FAILE", --设置一级合伙人失败 | |||
CLUB_CHANGE_BAO_JIAN_NAME = "CLUB_CHANGE_BAO_JIAN_NAME",--修改包间名 | |||
CLUB_CALUATE_ACTIVE_GAME = "CLUB_CALUATE_ACTIVE_GAME",--激活游戏列表更新 | |||
UPDATE_SCOREVIEW_SIZE = "UPDATE_SCOREVIEW_SIZE",--更新滑动区域 | |||
--排名赛事件分发 | |||
CLUB_ALL_PEOPLE_MATCH = "CLUB_ALL_PEOPLE_MATCH",--排名赛管理 | |||
CLUB_MATCH_LEVEL_LOG = "CLUB_MATCH_LEVEL_LOG",--升级记录 | |||
CLUB_MATCH_TEAM_LEVEL = "CLUB_MATCH_TEAM_LEVEL",--战队升级 | |||
CLUB_MATCH_LEVEL_UPGRADE = "CLUB_MATCH_LEVEL_UPGRADE",--战队升级 | |||
CLUB_MATCH_JUDGE = "CLUB_MATCH_JUDGE", --裁判 | |||
CLUB_TEAM_VIEW = "CLUB_TEAM_VIEW", --打开下级界面 | |||
--UNION | |||
CLUB_UNION_CHECK_MASTER = "CLUB_UNION_CHECK_MASTER", -- 查询主盟(已加入) | |||
CLUB_UNION_HITS = "CLUB_UNION_HITS", -- 主盟红点 | |||
CLUB_UNION_JOIN_MASTER_LIST = "CLUB_UNION_JOIN_MASTER_LIST", --申请加入主盟的列表 | |||
CLUB_UNION_MESSAGE = "CLUB_UNION_MESSAGE", --主盟的消息列表 | |||
CLUB_UNION_SLAVE_UPDATE = "CLUB_UNION_SLAVE_UPDATE", --刷新fu盟的列表 | |||
CLUB_UNION_SLAVE_UPDATE_LEVEL = "CLUB_UNION_SLAVE_UPDATE_LEVEL", --副盟的个人信息 | |||
CLUB_UNION_CLUB_BELONG = "CLUB_UNION_CLUB_BELONG", --亲友圈归属 | |||
CLUB_UNION_CLUB_BELONG_LIST = "CLUB_UNION_CLUB_BELONG_LIST", --亲友圈归属list | |||
} | |||
STORE_TYPE = { | |||
BUY_ZUANSHI = 0, --购买钻石 | |||
BUY_HUANLEDOU = 1, --购买欢乐豆 | |||
CHECK_HISTORY = 2, --购买记录 | |||
CHANGE_COIN = 4, --兑换金币 | |||
CHANGE_LIQUAN = 5, --礼券兑换实物 | |||
CHANGE_QYQBG = 81, --亲友圈背景兑换 | |||
CHANGE_DTBG = 82, --大厅背景兑换 | |||
CHANGE_LTQP = 83, --聊天气泡兑换 | |||
CHANGE_YYQP = 84, --语音气泡兑换 | |||
} | |||
INVITE_NEW_FRIEND = { | |||
NOENOUGH_ADDITION = 0,--不满足条件 | |||
ENOUGH_ADDITION = 1, --满足条件 | |||
HAVED_PRIZED =2, | |||
OLD_PLAYER =3,--老玩家不可領取 | |||
} | |||
PROTOCOL_TYPE = { | |||
COMMON = 1, | |||
COIN = 2, | |||
MATCH = 3, | |||
} | |||
COIN_LEVEL = { | |||
INIT = 10, -- 初级金币场 | |||
MIDDLE = 20, -- 中级金币场 | |||
HIGH = 30, -- 高级金币场 | |||
} | |||
COIN_TEXT_NAME = { | |||
[COIN_LEVEL.INIT] = "初级场", | |||
[COIN_LEVEL.MIDDLE] = "中级场", | |||
[COIN_LEVEL.HIGH] = "高级场", | |||
} | |||
COIN_SERVER_LEVEL = { | |||
[0] = "钻石模式"; | |||
[1] = "初级场"; | |||
[2] = "中级场"; | |||
[3] = "高级场"; | |||
} | |||
--是否启用新俱乐部代码 | |||
IS_USER_NEW_CLUB = true | |||
NOTICE_REDPOINT = { | |||
--公告里面 | |||
[1] = "notice_security",--超强防护 | |||
[2] = "tasks_groupTasks",--亲友圈活动 | |||
[3] = "notice_brand",--品牌力量 | |||
[4] = "notice_greenNotice",--绿色公告 | |||
[5] = "tasks_newGame",--新游上线(最新) | |||
--[6] = "notice_gameUpdate",--游戏更新 | |||
[7] = "notice_goldMatch",--金币场 | |||
[8] = "tasks_newGamePuYu",--网页游戏 | |||
[9] = "tasks_newGameXiYou",--网页游戏 | |||
[10] = "tasks_newGameDDH",--新游(倒倒胡) | |||
[11] = "notice_greenWelfare",--绿色公益 | |||
[12] = "notice_coBranding",--合作品牌 | |||
[13] = "tasks_xianyouji",--合作品牌 | |||
[14] = "tasks_meilixiushan",--美丽秀山 | |||
[15] = "tasks_hongbaoquan",--红包券 | |||
} | |||
ACTIVITY_REDPOINT = { | |||
--金币场 | |||
COIN_GAME_FULI = "everyWelfare",--金币场每日福利 | |||
COIN_GAME_FREE_GOLD = "freeGold",--金币场免费金币 | |||
--大厅 | |||
SYSTEM_MESSAGE = "message",--邮件消息 | |||
SYSTEM_IDENTIFY = "identify",--实名认证 | |||
AGENT = "agent", | |||
} | |||
LoginType = { | |||
LOGIN_TYPE_WEIXIN = 0, --微信登录 | |||
LOGIN_TYPE_PHONE = 1, --手机密码登录 | |||
LOGIN_TYPE_PHONE_CHECKCODE = 2, --手机验证码登陆 | |||
LOGIN_TYPE_ID = 3, --ID登录 | |||
LOGIN_TYPE_PHONE_REGISTER = 5, --手机注册 | |||
} | |||
ChangePlayerInfo = { | |||
PHONE_RESET = 1, --手机密码重置 | |||
REPLCACE_PHONE = 2, --手机替换 | |||
} | |||
BIND_TYPE = { | |||
PHONE = 0, --绑定手机 | |||
WEIXIN = 3, --绑定微信 | |||
WEIXIN_TWICE_BIND = 4, --二次授权绑定 | |||
BIND_TYPE_PASSWORD = 5, --密码强制设置 | |||
} | |||
BIND_TYPE_RESULT = { | |||
PHONE = 0, --绑定手机成功 | |||
CHECKCODE_FAILED = 1, --验证码错误 | |||
PHONE_BIND_FAILED = 2, --已绑定过手机号,无需再次绑定 | |||
PHONE_BINDED_OTHER_FAILED = 5, --该手机号已经被其他游戏ID绑定,请更换手机号再次绑定 | |||
WEIXIN = 6, --绑定微信成功 | |||
WEIXINBINDED_OTHER_FAILED = 7, --该微信号已绑定过其他游戏账号 | |||
WEIXIN_TWICE_BIND = 8, --二次授权绑定成功 | |||
USER_SET_PASSWORD = 9, --用户设置密码成功 | |||
} |
@@ -0,0 +1,309 @@ | |||
local isLoginData = false | |||
local isUpdateData = false | |||
local function gotoRoom() | |||
local loginInfo = app.user.loginInfo | |||
if loginInfo.gameId > 0 and loginInfo.tid > 0 then | |||
if not isLoginData or not isUpdateData then | |||
app.waitDialogManager:closeWaitNetworkDialog() | |||
return | |||
end | |||
app.waitDialogManager:closeWaitNetworkDialog() | |||
-- 进入房间 | |||
local function enterRoom() | |||
app.hall:requestEnterRoom(loginInfo.gameId, loginInfo.tid, app.protocolType) | |||
end | |||
-- 尝试进入房间 | |||
local function tryEnterRoom() | |||
local result, subGameId, missingFiles = app.subGameManager:checkGameFiles(loginInfo.gameId) | |||
if not result then | |||
logD("GlobalEvent::gotoRoom() 发现子游戏文件缺失,gameId = "..subGameId) | |||
for k,v in pairs(missingFiles) do | |||
logD(v); | |||
end | |||
local function onOk() | |||
app.subGameManager:clearGame(subGameId, function() | |||
downloadSubGame(subGameId, tryEnterRoom); | |||
end); | |||
end | |||
showConfirmDialog("发现文件缺失,点击确定开始修复", onOk); | |||
else | |||
enterRoom(); | |||
end | |||
end | |||
local isInstall = app.subGameManager:isInstaller(loginInfo.gameId) | |||
local isNeedUpdate = app.subGameManager:isNeedUpdate(loginInfo.gameId) | |||
if not isInstall or isNeedUpdate then | |||
downloadSubGame(loginInfo.gameId, tryEnterRoom) | |||
return | |||
end | |||
tryEnterRoom() | |||
end | |||
end | |||
-- 侦听全局的socket重连成功消息 | |||
function netConnectSucceed() | |||
-- 清空之前通过Protocol:sendResponse所有的消息注册函数 | |||
local function clearAllRegMsg() | |||
for i, v in pairs(g_regMsgCallBackFuncs) do | |||
v() | |||
end | |||
print("连接成功,清空所有之前通过Protocol:sendResponse注册的网络回调函数, 回到函数个数:" .. table.nums(g_regMsgCallBackFuncs)) | |||
g_regMsgCallBackFuncs = { } | |||
end | |||
app:addEventListener("socketConnectSucceed", clearAllRegMsg) | |||
end | |||
-- 绑定角色登陆成功的全局事件 | |||
local function actorLoginSucceed() | |||
-- 角色登陆成功后拉取消息全部返回完毕后拉取战斗 | |||
local function onLoginSuccessed() | |||
app.waitDialogManager:closeTransparencyMask(); | |||
local loginInfo = app.user.loginInfo | |||
print("GlobalEvent onLoginSuccessed :"..table.tostring(loginInfo)) | |||
local currentView = app:getCurrentView(); | |||
-- 参数不正确的情况下直接进入到大厅界面,省事 | |||
if not loginInfo or not currentView then | |||
--app:gotoView(import("luaScript.Views.Main.MainView"):new()); | |||
gotoMainView() | |||
app.user:dispatchEvent({name = "onMainViewLoginSuccessed"}) | |||
return | |||
end | |||
--在比赛中 | |||
if loginInfo and loginInfo.matchFlag == 1 then | |||
local function gotoMatch() | |||
local MatchEvents = require("luaScript.Views.Match.Constant.MatchEvents") | |||
local ProtocolMatchMessage = require("luaScript.Protocol.Match.ProtocolMatchMessage") | |||
local request=ProtocolMatchMessage.MatchEnter:new() | |||
request.uid = loginInfo.uid | |||
request.userInfo = app.user.userInfo | |||
dump(request) | |||
app.waitDialogManager:showWaitNetworkDialog("获取比赛信息..."); | |||
app.mainScene:sendMsg(app.match, MatchEvents.ENTER_MATCH, request, function(status, response) | |||
-- print(table.tostring(response)) | |||
end) | |||
end | |||
local isInstall = app.subGameManager:isInstaller(loginInfo.gameId) | |||
local isNeedUpdate = app.subGameManager:isNeedUpdate(loginInfo.gameId) | |||
if not isInstall or isNeedUpdate then | |||
downloadSubGame(loginInfo.gameId, gotoMatch) | |||
return | |||
end | |||
gotoMatch() | |||
return | |||
end | |||
-- 看玩家数据是不是在房间中 | |||
if loginInfo.gameId > 0 and loginInfo.tid > 0 then | |||
-- 如果没有配置信息,只能进大厅 | |||
local gameConfig = getSubGameConfig(loginInfo.gameId) | |||
if not gameConfig then | |||
--app:gotoView(import("luaScript.Views.Main.MainView"):new()); | |||
gotoMainView() | |||
app.user:dispatchEvent({name = "onMainViewLoginSuccessed"}) | |||
return | |||
end | |||
if loginInfo.serverLevel >= COIN_LEVEL.INIT and loginInfo.serverLevel <= COIN_LEVEL.HIGH + 10 then --金币场区间为10~40 | |||
app.protocolType = PROTOCOL_TYPE.COIN | |||
end | |||
isLoginData=true | |||
app.waitDialogManager:showWaitNetworkDialog() | |||
gotoRoom() | |||
-- -- 请求进入房间 | |||
-- local function enterRoom() | |||
-- app.hall:requestEnterRoom(loginInfo.gameId, loginInfo.tid) | |||
-- end | |||
-- local isInstall = app.subGameManager:isInstaller(loginInfo.gameId) | |||
-- local isNeedUpdate = app.subGameManager:isNeedUpdate(loginInfo.gameId) | |||
-- if not isInstall or isNeedUpdate then | |||
-- downloadSubGame(loginInfo.gameId, enterRoom) | |||
-- return; | |||
-- end | |||
-- enterRoom() | |||
else | |||
-- 若果正在显示总结算,则不理 | |||
if isShowCountAll() then | |||
return | |||
end | |||
-- 如果玩家不在房间中,分两种情况 | |||
-- 一种是现在的界面就是在大厅中。则什么都不用做,保持当前状态 | |||
-- 另一种是现在的界面不在大厅中,则需要重新进入大厅界面 | |||
if "MainView" ~= currentView.__cname then | |||
--app:gotoView(import("luaScript.Views.Main.MainView"):new()); | |||
gotoMainView() | |||
end | |||
app.user:dispatchEvent({name = "onMainViewLoginSuccessed"}) | |||
end | |||
end | |||
app.user:addEventListener("onLoginSuccessed", onLoginSuccessed) | |||
end | |||
local function actorLoginFailed() | |||
local function OnActorLoginFailed(event) | |||
local errCode = event.errCode | |||
if errCode then | |||
-- 1: 电话号码未绑定微信 2: 密码错误 | |||
local errString = | |||
{ | |||
[1] = "您的账号还没有绑定,请先使用【微信登陆】并在玩家信息中绑定【手机】账号", | |||
[2] = "密码错误", | |||
[3] = "账号已经禁止使用", | |||
[4] = "验证码错误", | |||
[7] = "该手机号已绑定过其他游戏账号", | |||
[8] = "该手机号还未注册", | |||
[9] = "没有此用户", | |||
} | |||
local message = errString[errCode] or "手机号登录失败 "..tostring(errCode); | |||
if tonumber(errCode) == 1 then | |||
showConfirmDialog(message,nil,nil,25); | |||
else | |||
showConfirmDialog(message); | |||
end | |||
end | |||
end | |||
app.user:addEventListener("onPhoneLoginErrResponse", OnActorLoginFailed) | |||
end | |||
function registerEnterRoomEvent() | |||
local function onEnterRoomSuccess(event) | |||
local gameId = event.gameId or 0; | |||
local gameType = event.gameType or 0; | |||
--目前只有金币场用到,用于区分是进入房间成功还是断线重连(金币场的gameStatus无法使用) | |||
local param = event.param; | |||
runInNextFrame(function() | |||
local roomViewName = getSubGameRoomView(gameId, gameType, app.protocolType) | |||
logD("onEnterRoomSuccess() roomViewName = " .. roomViewName) | |||
if roomViewName then | |||
local arr = string.split(roomViewName, ".") | |||
local len = table.nums(arr) | |||
local currentView = app:getCurrentView(); | |||
if currentView then | |||
logD("onEnterRoomSuccess() currentName = " .. currentView.__cname) | |||
else | |||
logD("onEnterRoomSuccess() currentView is nil") | |||
end | |||
if currentView and currentView.__cname == arr[len] then | |||
-- 当前正是在我想去的房间里面 | |||
logD("onEnterRoomSuccess() do nothing") | |||
else | |||
logD("onEnterRoomSuccess() goto view " .. roomViewName) | |||
app:gotoView(import(roomViewName):new(param)); | |||
end | |||
end | |||
end) | |||
end | |||
app.hall:addEventListener("onEnterRoomSuccess", onEnterRoomSuccess) | |||
end | |||
function registerKickoutEvent() | |||
local function onServerKickout() | |||
local function onClickOk() | |||
app.plugin:logout(); | |||
end | |||
app.net.isNeedReconnect = false | |||
app.net:close(); | |||
showConfirmDialog("数据异常,请重新登录", onClickOk)--"您的账号在其他地方登陆,您被强制下线" | |||
end | |||
app.user:addEventListener("onServerKickOutResponse", onServerKickout) | |||
end | |||
--子游戏更新获取完成事件 | |||
function registerSubGameListEvent() | |||
local function getSubGameListSuccessed() | |||
if not isUpdateData then | |||
isUpdateData=true | |||
gotoRoom() | |||
end | |||
end | |||
app.serverConfigs:addEventListener("getSubGameListSuccessed", getSubGameListSuccessed) | |||
end | |||
--绑定手机结果/绑定微信/二次授权 | |||
function registerBindAppEvent() | |||
local function onBindResponse(event) | |||
if not event or not event.response then | |||
return | |||
end | |||
local ret = tonumber(event.response.ret); | |||
local tips = | |||
{ | |||
[0] = "绑定成功", | |||
[1] = "验证码错误", | |||
[2] = "已绑定过手机号,无需再次绑定", | |||
[5] = "该手机号已经被其他游戏ID绑定,请更换手机号再次绑定", | |||
[6] = "绑定成功", | |||
[7] = "该微信号已绑定过其他游戏账号", | |||
[8] = "绑定成功", | |||
[9] = "设置成功", | |||
} | |||
local msg = tips[ret] or "未知错误:"..tostring(ret) | |||
showConfirmDialog(msg, function() end) | |||
end | |||
app.user:addEventListener("onBindResponse", onBindResponse) | |||
end | |||
--修改手机号/修改密码 | |||
function registerChangeAppEvent() | |||
local function onChangePlayerInfo(event) | |||
if not event or not event.response then | |||
return | |||
end | |||
local ret = tonumber(event.response.ret); | |||
local tips = | |||
{ | |||
[0] = "修改成功", | |||
[1] = "您的账号还没有绑定,请先使用【微信登陆】并在玩家信息中绑定【手机】账号", | |||
[2] = "密码错误", | |||
[3] = "账号已经禁止使用", | |||
[4] = "验证码错误", | |||
[7] = "该手机号已绑定过其他游戏账号", | |||
[8] = "该手机号还未注册", | |||
} | |||
local msg = tips[ret] or "未知错误:"..tostring(ret) | |||
showConfirmDialog(msg, function() end) | |||
end | |||
app.user:addEventListener("onChangePlayerInfo", onChangePlayerInfo) | |||
end | |||
-- 开始侦听所有全局事件 | |||
function startGlobalEvent() | |||
if isReviewWithMiniGame() then | |||
return | |||
end | |||
netConnectSucceed() | |||
actorLoginSucceed() | |||
actorLoginFailed() | |||
registerEnterRoomEvent() | |||
registerKickoutEvent() | |||
registerSubGameListEvent() | |||
registerBindAppEvent() | |||
registerChangeAppEvent() | |||
end |
@@ -0,0 +1,411 @@ | |||
local PluginAndroidLocation = require("luaScript.Plugins.PluginAndroidLocation"); | |||
local PluginAndroidGVoice = require("luaScript.Plugins.PluginAndroidGVoice"); | |||
local PluginAndroidDowloadManager = require("luaScript.Plugins.PluginAndroidDowloadManager"); | |||
local PluginAndroidPing = require("luaScript.Plugins.PluginAndroidPing"); | |||
local PluginIosPay = require("luaScript.Plugins.PluginIosPay"); | |||
local PluginIosLocation = require("luaScript.Plugins.PluginIosLocation"); | |||
local PluginIosGVoice = require("luaScript.Plugins.PluginIosGVoice"); | |||
local PluginIosDowloadManager = require("luaScript.Plugins.PluginIosDowloadManager"); | |||
local PluginWechat = require("luaScript.Plugins.PluginWechat"); | |||
local PluginWechatShare = require("luaScript.Plugins.PluginWechatShare"); | |||
local PluginYaya = require("luaScript.Plugins.PluginYaya"); | |||
local PluginZhuCheng = require("luaScript.Plugins.PluginZhuCheng"); | |||
local GlobalPlugin = class("GlobalPlugin"); | |||
function GlobalPlugin:ctor() | |||
-- 苹果支付插件 | |||
self.pluginIosPay = nil | |||
-- 微信 | |||
self.pluginWechat = nil; | |||
-- 微信分享 | |||
self.pluginWxShare = nil | |||
--yaya语音 | |||
self.pluginVoice = nil; | |||
--腾讯语音插件 | |||
self.pluginGVoice = nil | |||
-- GPS 定位插件 | |||
self.pluginGps = nil | |||
-- 初始化 | |||
self:init(); | |||
end | |||
function GlobalPlugin:init() | |||
-- 载入平台信息 | |||
local channelId = app.config.RomSetting.ChannelId; | |||
-- PC 版本强制设为100,防止配置错误导致的报错 | |||
if isWin32Platform() then | |||
channelId = 100 | |||
end | |||
if isAndroidPlatform() then | |||
self.pluginWechat = PluginWechat:new(); | |||
self.pluginVoice = PluginYaya:new(); | |||
self.pluginGps = PluginAndroidLocation:new() | |||
self.pluginDownloader = PluginAndroidDowloadManager:new() | |||
self.pluginPing = PluginAndroidPing:new() | |||
--self.pluginWxShare = PluginWechatShare:new() | |||
elseif isIOSPlatform() then | |||
self.pluginWechat = PluginWechat:new(); | |||
self.pluginVoice = PluginYaya:new(); | |||
self.pluginGps = PluginIosLocation:new(); | |||
self.pluginDownloader = PluginIosDowloadManager:new() | |||
--self.pluginWxShare = PluginWechatShare:new() | |||
if channelId == 105 then | |||
self.pluginIosPay = PluginIosPay:new(); | |||
end | |||
end | |||
-- 启动插件 | |||
self:start(); | |||
end | |||
-- 开启插件 | |||
function GlobalPlugin:start() | |||
-- 启动登陆插件 | |||
if self.pluginWechat then | |||
self.pluginWechat:start() | |||
end | |||
-- 下载SDK | |||
if self.pluginDownloader then | |||
self.pluginDownloader:start() | |||
end | |||
-- 网络监测 | |||
if self.pluginPing then | |||
self.pluginPing:start() | |||
end | |||
-- 定位 | |||
if self.pluginGps then | |||
local versionCode = getAppVersionName() | |||
log("versionCode:",versionCode) | |||
self.pluginGps:start() | |||
end | |||
end | |||
-- 注销账号 | |||
function GlobalPlugin:logout(tt) | |||
app.userManager:clearUserList(); | |||
cc.Application:getInstance():restart(); | |||
end | |||
-- 跳转网页 | |||
function GlobalPlugin:callUrl(url) | |||
logD("GlobalPlugin:callUrl(), url = ", url); | |||
if PluginDevice then | |||
PluginDevice:callVoid("openUrl", url); | |||
else | |||
logD("GlobalPlugin:callUrl(), PluginDevice is nil"); | |||
end | |||
end | |||
function GlobalPlugin:isShowThirdLogin() | |||
return self:isSupportWeiXin() | |||
end | |||
function GlobalPlugin:shareGame(tt, shareCallback) | |||
logD("GlobalPlugin:shareGame(), tt = ", table.tostring(tt)) | |||
if self.pluginWxShare then | |||
self:shareWxShare(tt, shareCallback) | |||
else | |||
self:shareWeiXin(tt, shareCallback) | |||
end | |||
end | |||
------------------------------------------- IosPay ------------------------------------------- | |||
function GlobalPlugin:startIosPay() | |||
logD("GlobalPlugin:startIosPay()") | |||
if self.pluginIosPay then | |||
self.pluginIosPay:start() | |||
else | |||
logD("GlobalPlugin:startIosPay(), self.pluginIosPay is nil") | |||
end | |||
end | |||
function GlobalPlugin:payIosPay(itemInfo) | |||
logD("GlobalPlugin:payIosPay(), tt = ", table.tostring(itemInfo)) | |||
if self.pluginIosPay then | |||
self.pluginIosPay:pay(itemInfo) | |||
else | |||
logD("GlobalPlugin:payIosPay(), self.pluginIosPay is nil") | |||
end | |||
end | |||
------------------------------------------- WeiXin ------------------------------------------- | |||
function GlobalPlugin:isSupportWeiXin() | |||
logD("GlobalPlugin:isSupportWeiXin()") | |||
if self.pluginWechat then | |||
local result = self.pluginWechat:isSupport() | |||
logD("GlobalPlugin:isSupportWeiXin(), result = ", tostring(result)) | |||
return result | |||
else | |||
logD("GlobalPlugin:isSupportWeiXin(), self.pluginWechat is nil") | |||
return false | |||
end | |||
end | |||
function GlobalPlugin:gotoWeiXin() | |||
logD("GlobalPlugin:gotoWeiXin()") | |||
if self.pluginWechat then | |||
self.pluginWechat:gotoWeiXin(); | |||
else | |||
logD("GlobalPlugin:gotoWeiXin(), self.pluginWechat is nil") | |||
end | |||
end | |||
function GlobalPlugin:loginWeiXin(tt) | |||
logD("GlobalPlugin:loginWeiXin(), tt = ", table.tostring(tt)) | |||
if self.pluginWechat then | |||
self.pluginWechat:login(tt); | |||
else | |||
logD("GlobalPlugin:loginWeiXin(), self.pluginWechat is nil") | |||
end | |||
end | |||
function GlobalPlugin:payWeiXin(tt) | |||
logD("GlobalPlugin:payWeiXin(), tt = ", table.tostring(tt)) | |||
if self.pluginWechat then | |||
self.pluginWechat:pay(tt); | |||
else | |||
logD("GlobalPlugin:payWeiXin(), self.pluginWechat is nil") | |||
end | |||
end | |||
function GlobalPlugin:shareWeiXin(tt, callback) | |||
logD("GlobalPlugin:shareWeiXin(), tt = ", table.tostring(tt)) | |||
if self.pluginWechat then | |||
self.pluginWechat:shareGame(tt, callback) | |||
else | |||
logD("GlobalPlugin:shareWeiXin(), self.pluginWechat is nil") | |||
end | |||
end | |||
-- 显示微信下载的对话框 | |||
function GlobalPlugin:showWeiXinDownloadDialog() | |||
local text = "未安装【微信】,是否前往下载【微信】?" | |||
local okBtnImage = "res/ui/zy_tongyong/zy_button/btn_like_xiazai.png" | |||
local okCallBack = function() | |||
app.plugin:callUrl("http://weixin.qq.com/"); | |||
end | |||
local cancelCallBack = function() | |||
end | |||
showConfirmDialog(text, okCallBack, cancelCallBack, 26, okBtnImage) | |||
return; | |||
end | |||
------------------------------------------- wxshare ------------------------------------------- | |||
-- 初始化微信分享 | |||
function GlobalPlugin:initWxShare( appid, secret ) | |||
logD("GlobalPlugin:initWxShare(), appid = "..appid..", secret = "..secret) | |||
if isWin32Platform() then | |||
logD("GlobalPlugin:initWxShare(), win32") | |||
return | |||
end | |||
if isReviewVersion() then | |||
logD("GlobalPlugin:initWxShare(), review version") | |||
return | |||
end | |||
local PluginConfig = require("preload.PluginConfig") | |||
if PluginConfig and PluginConfig.isAppStoreVersion then | |||
-- 苹果商城的版本因为包名发生了变化,是不能使用多微信分享的。 | |||
return | |||
end | |||
if not self.pluginWxShare then | |||
self.pluginWxShare = PluginWechatShare:new() | |||
end | |||
if self.pluginWxShare then | |||
self.pluginWxShare:start(appid, secret); | |||
end | |||
end | |||
function GlobalPlugin:shareWxShare(tt, callback) | |||
logD("GlobalPlugin:shareWxShare(), tt = ", table.tostring(tt)) | |||
if self.pluginWxShare then | |||
self.pluginWxShare:shareGame(tt, callback) | |||
else | |||
logD("GlobalPlugin:shareWxShare(), self.pluginWxShare is nil") | |||
end | |||
end | |||
------------------------------------------- voice ------------------------------------------- | |||
-- 成功登陆到游戏 | |||
function GlobalPlugin:startVoice() | |||
logD("GlobalPlugin:startVoice()") | |||
if self.pluginVoice then | |||
self.pluginVoice:start() | |||
else | |||
logD("GlobalPlugin:startVoice(), self.pluginVoice is nil") | |||
end | |||
end | |||
-- 开始录音 | |||
function GlobalPlugin:startRecord() | |||
logD("GlobalPlugin:startRecord()") | |||
if self.pluginVoice then | |||
self.pluginVoice:startRecord() | |||
else | |||
logD("GlobalPlugin:startRecord(), self.pluginVoice is nil") | |||
end | |||
end | |||
-- 结束录音 | |||
function GlobalPlugin:stopRecord() | |||
logD("GlobalPlugin:stopRecord()") | |||
if self.pluginVoice then | |||
self.pluginVoice:stopRecord() | |||
else | |||
logD("GlobalPlugin:stopRecord(), self.pluginVoice is nil") | |||
end | |||
end | |||
-- 取消录音 | |||
function GlobalPlugin:cancelRecord() | |||
logD("GlobalPlugin:cancelRecord()") | |||
if self.pluginVoice then | |||
self.pluginVoice:cancelRecord() | |||
else | |||
logD("GlobalPlugin:cancelRecord(), self.pluginVoice is nil") | |||
end | |||
end | |||
-- 播放录音 | |||
function GlobalPlugin:playRecord(filePath) | |||
log("GlobalPlugin:playRecord(), filePath = ", filePath); | |||
if self.pluginVoice then | |||
self.pluginVoice:playRecord(filePath) | |||
else | |||
logD("GlobalPlugin:playRecord(), self.pluginVoice is nil") | |||
end | |||
end | |||
-- 停止播放录音 | |||
function GlobalPlugin:stopPlayRecord() | |||
log("GlobalPlugin:stopPlayRecord() "); | |||
if self.pluginVoice then | |||
self.pluginVoice:stopPlayRecord() | |||
else | |||
logD("GlobalPlugin:stopPlayRecord(), self.pluginVoice is nil") | |||
end | |||
end | |||
-- 下载录音 | |||
function GlobalPlugin:downloadRecord(nUserId, recordUrl, downloadCallback) | |||
log("GlobalPlugin:downloadRecord(), nUserId = " .. nUserId .. ", recordUrl = " .. recordUrl); | |||
if self.pluginVoice then | |||
self.pluginVoice:downloadRecord(nUserId, recordUrl, downloadCallback); | |||
else | |||
logD("GlobalPlugin:downloadRecord(), self.pluginVoice is nil") | |||
end | |||
end | |||
------------------------------------------- gps ------------------------------------------- | |||
-- 更新GPS位置信息 | |||
function GlobalPlugin:updateLocation() | |||
logD("GlobalPlugin:updateLocation()") | |||
if self.pluginGps then | |||
self.pluginGps:updateLocation() | |||
else | |||
logD("GlobalPlugin:updateLocation() self.pluginGps is nil") | |||
end | |||
end | |||
-- 获取当前的GPS位置信息 | |||
function GlobalPlugin:getLocationInfo() | |||
logD("GlobalPlugin:getLocationInfo()") | |||
if self.pluginGps then | |||
return self.pluginGps:getLocationInfo() | |||
else | |||
logD("GlobalPlugin:getLocationInfo() self.pluginGps is nil") | |||
end | |||
end | |||
-- 获取定位服务开启状态 | |||
function GlobalPlugin:getLocationEnable() | |||
logD("GlobalPlugin:getLocationEnable()") | |||
if self.pluginGps then | |||
local status = self.pluginGps:getLocationEnable() | |||
logD("GlobalPlugin:getLocationEnable(), status = ", tostring(status)) | |||
return status | |||
else | |||
logD("GlobalPlugin:getLocationEnable() self.pluginGps is nil") | |||
return false | |||
end | |||
end | |||
-- 前往打开GPS | |||
function GlobalPlugin:openGPS() | |||
logD("GlobalPlugin:openGPS()"); | |||
if self.pluginGps then | |||
self.pluginGps:openGPS(); | |||
else | |||
logD("GlobalPlugin:openGPS() self.pluginGps is nil") | |||
end | |||
end | |||
------------------------------------------- ping ------------------------------------------- | |||
function GlobalPlugin:startPing() | |||
logD("GlobalPlugin:startPing()") | |||
if self.pluginPing then | |||
return self.pluginPing:startPing() | |||
else | |||
logD("GlobalPlugin:startPing(), self.pluginPing is nil") | |||
end | |||
end | |||
function GlobalPlugin:stopPing() | |||
logD("GlobalPlugin:stopPing()") | |||
if self.pluginPing then | |||
return self.pluginPing:stopPing() | |||
else | |||
logD("GlobalPlugin:stopPing(), self.pluginPing is nil") | |||
end | |||
end | |||
function GlobalPlugin:getPing() | |||
logD("GlobalPlugin:getPing()") | |||
if self.pluginPing then | |||
local result = self.pluginPing:getPing() | |||
logD("GlobalPlugin:getPing(), result = ", result) | |||
return result | |||
else | |||
logD("GlobalPlugin:getPing(), self.pluginPing is nil") | |||
return 0 | |||
end | |||
end | |||
------------------------------------------- downloader ------------------------------------------- | |||
function GlobalPlugin:createTask(url,path,onFinish,onProgress) | |||
logD("GlobalPlugin:createTask(), url = " .. url .. ", path = " .. path) | |||
if self.pluginDownloader then | |||
self.pluginDownloader:createTask(url,path,onFinish,onProgress) | |||
else | |||
logD("GlobalPlugin:createTask(), self.pluginDownloader is nil") | |||
end | |||
end | |||
return GlobalPlugin |
@@ -0,0 +1,4 @@ | |||
function gotoMainView(gameid,clubid) | |||
app:gotoView(import("luaScript.Views.Main.MainView"):new(gameid)) | |||
end |
@@ -0,0 +1,85 @@ | |||
--- | |||
-- ================================================================ | |||
-- 文件名: IClub.lua | |||
-- 描述: 亲友圈相关接口 | |||
-- 版权: Copyright © 2016-2019 公司名称 版权所有 | |||
-- 作者: Administrator | |||
-- 创建日期: 2019-10-22 | |||
-- 更新日期: 2019-10-22 | |||
-- 备注: | |||
-- ================================================================ | |||
-- | |||
local IClub = {} | |||
function IClub.getClubPhp () | |||
return app.club_php | |||
end | |||
--- | |||
-- 获取当前亲友圈id | |||
-- @return | |||
-- | |||
function IClub.getCurrentClubId () | |||
return app.club_php.clubID and tonumber(app.club_php.clubID) or 0 | |||
end | |||
--- | |||
-- 获取当前亲友圈数据 | |||
-- @return | |||
-- | |||
function IClub.getCurrentClubInfo() | |||
local clubId = IClub.getCurrentClubId() | |||
return IClub.getClubInfo(clubId) | |||
end | |||
--- | |||
-- 获取指定亲友圈数据 | |||
-- @param clubId | |||
-- @return | |||
-- | |||
function IClub.getClubInfo(clubId) | |||
local clubInfo = app.club_php:getClubInfo(clubId) | |||
return clubInfo | |||
end | |||
--- | |||
-- 当前是否在亲友圈里 | |||
-- @return | |||
-- | |||
function IClub.isInClub () | |||
return app.club_php.clubID and app.club_php.clubID ~= 0 | |||
end | |||
--- | |||
-- 是否可以解散房间 | |||
-- @return | |||
-- | |||
function IClub.getCanDismiss (callBack) | |||
if not IClub.isInClub() then | |||
return 1 | |||
end | |||
local clubInfo = IClub.getCurrentClubInfo() | |||
if not clubInfo then | |||
local clubId = IClub.getCurrentClubId() | |||
app.club_php:requestClubHomeInGame(clubId, function ( res ) | |||
local groupext = res.groupext or {} | |||
local playext = groupext.playext or {} | |||
logD("IClub.getCanDismiss", res.groupext) | |||
if type(callBack) == "function" then | |||
callBack({canDismiss = playext.can_dismiss}) | |||
end | |||
end) | |||
return | |||
end | |||
local groupext = clubInfo.groupext or {} | |||
local playext = groupext.playext or {} | |||
return playext.can_dismiss or 1 | |||
end | |||
function IClub.isAdmin() | |||
local clubInfo = IClub.getCurrentClubInfo() | |||
if not clubInfo then | |||
return false | |||
end | |||
local role = clubInfo.role | |||
local isAdmin = role == 2 or role == 3 | |||
return isAdmin | |||
end | |||
return IClub |
@@ -0,0 +1,51 @@ | |||
--- | |||
-- ================================================================ | |||
-- 文件名: IGameCommon.lua | |||
-- 描述: 子游戏引用大厅接口 | |||
-- 作者: Administrator | |||
-- 创建日期: 2020-2-18 | |||
-- 更新日期: 2020-2-18 | |||
-- 备注: | |||
-- ================================================================ | |||
-- | |||
local IGameCommon = {}; | |||
--[[ | |||
获取分享的二维码图片 | |||
]] | |||
function IGameCommon.getShareCRCodeTexture(callback) | |||
local clientConfig = app.serverConfigs.clientConfig | |||
local crCodeUrl = clientConfig and clientConfig.qrcode or "" | |||
if crCodeUrl == "" then | |||
showTooltip("未配置二维码地址") | |||
return | |||
end | |||
--download | |||
local urlfile = convertIconUrl(crCodeUrl) | |||
local fileName = getImageNameFromUrl(urlfile) | |||
local fullPath = cc.FileUtils:getInstance():getWritablePath()..fileName; | |||
local isExist = cc.FileSystem:fileExists(fullPath) | |||
if not isExist then | |||
getImageFromUrlWithTime(crCodeUrl, fileName, nil, function() | |||
local texture = loadTextureFromFile(fileName) | |||
if not texture then | |||
logD("IGameCommon getShareCRCodeTexture not found") | |||
return | |||
end | |||
if callback then | |||
callback(texture) | |||
end | |||
end) | |||
else | |||
local texture = loadTextureFromFile(fileName) | |||
if not texture then | |||
logD("IGameCommon getShareCRCodeTexture not found") | |||
return | |||
end | |||
if callback then | |||
callback(texture) | |||
end | |||
end | |||
end | |||
return IGameCommon; |
@@ -0,0 +1,30 @@ | |||
--- | |||
-- ================================================================ | |||
-- 文件名: IGameOverAward.lua | |||
-- 描述: 排名赛抽奖接口 | |||
-- 版权: Copyright © 2016-2019 公司名称 版权所有 | |||
-- 作者: Administrator | |||
-- 创建日期: 2019-10-22 | |||
-- 更新日期: 2019-10-22 | |||
-- 备注: | |||
-- ================================================================ | |||
-- | |||
local IGameOverAward = {} | |||
IGameOverAward.chouJiangData = nil | |||
function IGameOverAward.setAwardData(data) | |||
IGameOverAward.chouJiangData = data | |||
end | |||
function IGameOverAward.showAwardView() | |||
if not IGameOverAward.chouJiangData then | |||
return | |||
end | |||
local view = import("luaScript.Views.Club.Match.ClubMatchChouJiang"):new(IGameOverAward.chouJiangData) | |||
view:setAnchorPoint(cc.p(0.5, 0.5)) | |||
app:showWaitDialog(view) | |||
end | |||
return IGameOverAward |
@@ -0,0 +1,245 @@ | |||
--- | |||
-- ================================================================ | |||
-- 文件名: IPlayGameAgain.lua | |||
-- 描述: 子游戏结算再来一局功能接口 | |||
-- 版权: Copyright © 2016-2019 公司名称 版权所有 | |||
-- 作者: Administrator | |||
-- 创建日期: 2019-10-22 | |||
-- 更新日期: 2019-10-22 | |||
-- 备注: | |||
-- ================================================================ | |||
-- | |||
local IPlayGameAgain = {}; | |||
IPlayGameAgain.isAgainGameBol = false -- 是否再来一局 | |||
IPlayGameAgain.wanfa = "" -- 子游戏玩法 | |||
IPlayGameAgain.uidList = {} -- 待邀请玩家列表 | |||
IPlayGameAgain.isAgainGameBaoJianId = -1 -- 再来一局包间ID | |||
IPlayGameAgain.isAgainGameData = nil -- 再来一局接受邀请数据 | |||
IPlayGameAgain.isGameRuleChange = false -- 再来一局包间玩法是否被修改 | |||
IPlayGameAgain.gameRoomId = 0 -- 再来一局包间id | |||
IPlayGameAgain.myGameCreateStatus = false -- 玩家是否创建过房间 | |||
IPlayGameAgain.inviteView = nil -- 邀请框 | |||
function IPlayGameAgain.bindPlayAgainButton (btnPlayAgain, gameId, inviteInfo, inviteList, initCallback) | |||
local clubId = app.club_php.clubID or 0 | |||
local isInClub = clubId and clubId ~= 0 | |||
if not isInClub then | |||
logD("IPlayGameAgain.initPlayGameAgain", "当前玩家不在亲友圈内,不能再来一局"); | |||
btnPlayAgain:setVisible(false) | |||
return | |||
end | |||
if tolua.isnull(btnPlayAgain) then | |||
logD("IPlayGameAgain.bindPlayAgainButton", "再来一局按钮已经被释放") | |||
return | |||
end | |||
local isClosePlayAgain = IPlayGameAgain.isClosePlayAgain(gameId) | |||
btnPlayAgain:setVisible(not isClosePlayAgain) | |||
if isClosePlayAgain then | |||
if type(initCallback) == "function" then | |||
initCallback() | |||
end | |||
return | |||
end | |||
btnPlayAgain:registerClick(function () | |||
logD("===================inviteList==================:",table.tostring(inviteList)) | |||
IPlayGameAgain.setIsAgainGamebol(true, inviteInfo, inviteList) | |||
gotoMainView() | |||
end) | |||
local clubInfo = app.club_php:getClubInfo(clubId) | |||
if not clubInfo then | |||
logD("IPlayGameAgain.bindPlayAgainButton", "亲友圈信息不存在", "clubId:", clubId) | |||
if type(initCallback) == "function" then | |||
initCallback() | |||
end | |||
return | |||
end | |||
local baoJianId = IPlayGameAgain.getAgainGameBaoJianId() | |||
if baoJianId ~= -1 and clubInfo.settings and tonumber(clubInfo.settings.baoJianId) ~= tonumber(baoJianId) and clubInfo.mode == 0 then | |||
app.club_php:requestRuleSet(app.club_php.clubID, baoJianId, 1, 1) | |||
end | |||
if type(initCallback) == "function" then | |||
initCallback() | |||
end | |||
end | |||
--- | |||
-- 收到再来一局邀请信息时,弹出邀请弹框 | |||
-- @param data | |||
-- @return | |||
-- | |||
function IPlayGameAgain.showClubInviteDialog (data, agreeCallback, closeCallback) | |||
--房间邀请通知 | |||
local content = data.content | |||
local clubId = data.clubId | |||
local inviteView = IPlayGameAgain.inviteView | |||
local viewType = type(inviteView) | |||
if inviteView and viewType == "userdata" then | |||
--提示框已存在 | |||
return | |||
end | |||
local function removeInviteView() | |||
if not tolua.isnull(IPlayGameAgain.inviteView) then | |||
-- IPlayGameAgain.inviteView:removeFromParent() | |||
IPlayGameAgain.inviteView = nil | |||
end | |||
end | |||
local function onBtnCloseClicked() | |||
--关闭提示框时清空数据,用于下次弹出 | |||
removeInviteView() | |||
if type(closeCallback) == "function" then | |||
closeCallback() | |||
end | |||
end | |||
local function onBtnAgreeClicked() | |||
removeInviteView() | |||
gotoMainView() | |||
if type(agreeCallback) == "function" then | |||
agreeCallback() | |||
end | |||
end | |||
inviteView = import("luaScript.Views.Club.ClubInviteRoomNew"):new(clubId, content, onBtnCloseClicked, onBtnAgreeClicked) | |||
inviteView:setAnchorPoint(cc.p(0.5, 0.5)) | |||
app:showWaitDialog(inviteView,0) | |||
IPlayGameAgain.inviteView = inviteView | |||
end | |||
--- | |||
-- 是否关闭再来一局功能 | |||
-- 默认关闭 | |||
-- @return | |||
-- | |||
function IPlayGameAgain.isClosePlayAgain (gameId) | |||
local isClosePlayAgain = true | |||
local config = getSubGameConfig(gameId) | |||
if not config then | |||
logD("IPlayGameAgain.isClosePlayAgain", "读取子游戏配置为空") | |||
return isClosePlayAgain | |||
end | |||
if config.gameDataConfig and config.gameDataConfig.isClosePlayAgain ~= nil then | |||
logD("IPlayGameAgain.isClosePlayAgain", "子游戏再来一局功能已打开") | |||
isClosePlayAgain = config.gameDataConfig.isClosePlayAgain == true | |||
end | |||
return isClosePlayAgain | |||
end | |||
--- | |||
-- 设置是否再来一局 | |||
-- @param bol 是否再来一局 | |||
-- @param wanfadata 子游戏玩法 | |||
-- @param uidList 待邀请玩家列表 | |||
-- @return | |||
-- | |||
function IPlayGameAgain.setIsAgainGamebol(bol, wanfadata, uidList) | |||
logD("IPlayGameAgain.setIsAgainGamebol") | |||
IPlayGameAgain.isAgainGameBol = bol | |||
if wanfadata then | |||
IPlayGameAgain.wanfa = wanfadata | |||
end | |||
if uidList then | |||
IPlayGameAgain.uidList = uidList or {} | |||
end | |||
end | |||
--- | |||
-- 是否再来一局 | |||
-- @return | |||
-- | |||
function IPlayGameAgain.getIsAgainGamebol() | |||
return IPlayGameAgain.isAgainGameBol, IPlayGameAgain.wanfa, IPlayGameAgain.uidList; | |||
end | |||
--- | |||
-- 再来一局包间id | |||
-- @param idx | |||
-- @return | |||
-- | |||
function IPlayGameAgain.setAgainGameBaoJianId(idx) | |||
IPlayGameAgain.isAgainGameBaoJianId = idx | |||
end | |||
--- | |||
-- 获取再来一局包间id | |||
-- @return | |||
-- | |||
function IPlayGameAgain.getAgainGameBaoJianId() | |||
return IPlayGameAgain.isAgainGameBaoJianId; | |||
end | |||
--- | |||
-- 保存再来一局接受邀请数据 | |||
-- @param data | |||
-- @return | |||
-- | |||
function IPlayGameAgain.setAgainGameInvitedata(data) | |||
IPlayGameAgain.isAgainGameData = data | |||
end | |||
--- | |||
-- 获取再来一局接受邀请数据 | |||
-- @return | |||
-- | |||
function IPlayGameAgain.getAgainGameInvitedata() | |||
return IPlayGameAgain.isAgainGameData; | |||
end | |||
--- | |||
-- 保存再来一局玩法状态 | |||
-- 检测点再来一局的时候,玩法是否被修改。如果是修改那么提示创建失败。 | |||
-- @param bol | |||
-- @return | |||
-- | |||
function IPlayGameAgain.setRuleChangeStatus(bol) | |||
IPlayGameAgain.isGameRuleChange = bol | |||
end | |||
--- | |||
-- 获取再来一局玩法状态 | |||
-- 检测点再来一局的时候,玩法是否被修改。如果是修改那么提示创建失败。 | |||
-- @return | |||
-- | |||
function IPlayGameAgain.getRuleChangeStatus() | |||
return IPlayGameAgain.isGameRuleChange | |||
end | |||
--- | |||
-- 保存房间id | |||
-- 邀请的时候需要用到数据 | |||
-- @param idx | |||
-- @return | |||
-- | |||
function IPlayGameAgain.setGameRoomId(idx) | |||
IPlayGameAgain.gameRoomId = idx | |||
end | |||
--- | |||
-- 获取房间id | |||
-- @return | |||
-- | |||
function IPlayGameAgain.getGameRoomId() | |||
return IPlayGameAgain.gameRoomId; | |||
end | |||
--- | |||
-- 保存玩家是否创建过房间 | |||
-- @param bol | |||
-- @return | |||
-- | |||
function IPlayGameAgain.setMyGameCreateStatus(bol) | |||
IPlayGameAgain.myGameCreateStatus = bol | |||
end | |||
--- | |||
-- 获取玩家是否创建过房间 | |||
-- @return | |||
-- | |||
function IPlayGameAgain.getMyGameCreateStatus() | |||
return IPlayGameAgain.myGameCreateStatus; | |||
end | |||
return IPlayGameAgain; |
@@ -0,0 +1,7 @@ | |||
dd = dd or {} | |||
dd.IClub = require("luaScript.Interface.IClub") | |||
dd.IPlayGameAgain = require("luaScript.Interface.IPlayGameAgain"); | |||
dd.IGameOverAward = require("luaScript.Interface.IGameOverAward"); | |||
dd.IGameCommon = require("luaScript.Interface.IGameCommon"); |
@@ -0,0 +1,92 @@ | |||
MJFramework={} | |||
local paths={} | |||
local files={} | |||
function MJFramework.MJImport(name,gameId) | |||
local fileName=string.gsub(name, "%.", "/") | |||
local gameConfig = getSubGameConfig(gameId or app.gameId) | |||
local rootName=gameConfig.rootName | |||
local findMjHsb = string.find(name, 'mj_hsb') | |||
-- 判断是否有旧mj_hsb路径 | |||
if not findMjHsb then | |||
local newFileName=string.gsub(fileName, "MJ", gameConfig.fileName) | |||
newFileName=string.gsub(newFileName, "mj", rootName) | |||
local newName=string.gsub(name, "MJ", gameConfig.fileName) | |||
newName=string.gsub(newName, "mj", rootName) | |||
local luaFile = newFileName..".lua" | |||
local luacFile = newFileName..".luac" | |||
local isFileExist = cc.FileUtils:getInstance():isFileExist(luacFile) | |||
if not isFileExist then | |||
isFileExist = cc.FileUtils:getInstance():isFileExist(luaFile) | |||
end | |||
if isFileExist then | |||
name=newName | |||
end | |||
else | |||
local newFileName=string.gsub(fileName, "MJ", gameConfig.fileName) | |||
newFileName=string.gsub(newFileName, "mj_hsb", rootName) | |||
local newName=string.gsub(name, "MJ", gameConfig.fileName) | |||
newName=string.gsub(newName, "mj_hsb", rootName) | |||
local luaFile = newFileName..".lua" | |||
local luacFile = newFileName..".luac" | |||
local isFileExist = cc.FileUtils:getInstance():isFileExist(luacFile) | |||
if not isFileExist then | |||
isFileExist = cc.FileUtils:getInstance():isFileExist(luaFile) | |||
end | |||
if isFileExist then | |||
name=newName | |||
end | |||
end | |||
files[name]=true | |||
print("MJImport:"..name) | |||
return require(name) | |||
end | |||
function MJFramework.ImportWanFa(name,gameId) | |||
local fileName=string.gsub(name, "%.", "/") | |||
local gameConfig = getSubGameConfig(gameId or app.gameId) | |||
local rootName=gameConfig.rootName | |||
local newFileName=string.gsub(fileName, "MJ", gameConfig.fileName) | |||
local newName=string.gsub(name, "MJ", gameConfig.fileName) | |||
local luaFile = newFileName..".lua" | |||
local luacFile = newFileName..".luac" | |||
local isFileExist = cc.FileUtils:getInstance():isFileExist(luacFile) | |||
if not isFileExist then | |||
isFileExist = cc.FileUtils:getInstance():isFileExist(luaFile) | |||
end | |||
if isFileExist then | |||
name=newName | |||
end | |||
print("ImportWanFa:"..name) | |||
files[name]=true | |||
return require(name) | |||
end | |||
function MJFramework.Clean() | |||
for fileName,v in pairs(files) do | |||
print("Clean:"..fileName) | |||
package.loaded[fileName] = nil | |||
end | |||
files={} | |||
end | |||
function MJFramework.MJFrameworkClassImprot(name) | |||
print("MJFrameworkClassImprot:"..name) | |||
files[name]=true | |||
return require(name) | |||
end |
@@ -0,0 +1,299 @@ | |||
local Map = class("Map"); | |||
require("luaScript.Map.MapDrawer")(Map); | |||
Map.ObstacleType = | |||
{ | |||
-- 不是障碍块 | |||
ObstacleNone = 1, | |||
-- 是障碍块 | |||
ObstacleNormal = 0, | |||
} | |||
-- TileWidth | |||
Map.TileWidth = 60 | |||
-- tileHeight | |||
Map.TileHeight = 30 | |||
-- 构造函数 | |||
function Map:ctor() | |||
-- 默认构造一个1136 X 640的地图 | |||
-- self:initWidthAndHeight(1136, 640, 60, 30); | |||
-- 障碍信息 | |||
self.obstacles = cc.CAStar:new(); | |||
-- 当障碍块改变时回调 | |||
self.ObstacleChanged = nil; | |||
end | |||
-- 重新计算地图 | |||
function Map:recalculate() | |||
self.TileHalfWidth = self.TileWidth / 2; | |||
self.TileHalfHeight = self.TileHeight / 2; | |||
-- 根据地图大小和tile的大小,计算tile的个数以及tile的偏移 | |||
local widthLen = math.ceil(self.MapWidth / self.TileWidth); | |||
local heightLen = math.ceil(self.MapHeight / self.TileHeight); | |||
self.TileCountX = widthLen + heightLen; | |||
self.TileCountY = widthLen + heightLen; | |||
-- X轴不需要偏移,只偏移Y轴 | |||
self.OffsetX = 0; | |||
self.OffsetY = heightLen; | |||
end | |||
-- 初始化地图的宽度和高度 | |||
function Map:initWidthAndHeight(width, height, tileWidth, tileHeight) | |||
self.MapWidth = width; | |||
self.MapHeight = height; | |||
self.TileWidth = tileWidth; | |||
self.TileHeight = tileHeight; | |||
-- 重新计算地图 | |||
self:recalculate(); | |||
end | |||
-- 初始化障碍块 | |||
function Map:initObstacles() | |||
self.obstacles:resize(self.TileCountX , self.TileCountY); | |||
end | |||
-- 增加一个障碍块 | |||
-- x y 为逻辑坐标 | |||
function Map:addObstacle(x, y) | |||
-- 如果不在地图内则添加不成功 | |||
if self:isInMap(x, y) == false or self:isObstacle(x, y) then | |||
return | |||
end | |||
self.obstacles:setBlock(x , y , Map.ObstacleType.ObstacleNormal); | |||
if self.ObstacleChanged then | |||
self.ObstacleChanged(x , y , Map.ObstacleType.ObstacleNormal); | |||
end | |||
end | |||
-- 删除一个障碍块 | |||
-- x y 为逻辑坐标 | |||
function Map:removeObstacle(x, y) | |||
if self:isInMap(x, y) then | |||
self.obstacles:setBlock(x , y , Map.ObstacleType.ObstacleNone); | |||
if self.ObstacleChanged then | |||
self.ObstacleChanged(x , y , Map.ObstacleType.ObstacleNone); | |||
end | |||
end | |||
end | |||
-- 判断一个点是否是障碍点 | |||
-- x y 为逻辑坐标 | |||
function Map:isObstacle(x, y) | |||
if self:isInMap(x, y) then | |||
return self.obstacles:isBlock(x,y); | |||
end | |||
return false; | |||
end | |||
-- 根据点的坐标或者障碍数据 | |||
function Map:getObstacle(x, y) | |||
if self:isInMap(x, y) == false then | |||
return 0; | |||
end | |||
return self.obstacles:getBlock(x,y); | |||
end | |||
-- 判断一个坐标点是否在地图内 | |||
function Map:isInMap(x, y) | |||
if x < 0 or y < 0 then | |||
print("x or y is less 0", "current x is", x, "current y is", y); | |||
return false; | |||
end | |||
if x >= self.TileCountX or y >= self.TileCountY then | |||
print("Map:TileCountX is", self.TileCountX, " current x is", x); | |||
print("Map:TileCountY is", self.TileCountY, " current y is", y); | |||
return false; | |||
end | |||
return true; | |||
end | |||
function Map:loadFromLuaNode(luaNode) | |||
-- 初始化地图数据 | |||
self:initWidthAndHeight(tonumber(luaNode.width), tonumber(luaNode.height), tonumber(luaNode.tileWidth), tonumber(luaNode.tileHeight)); | |||
if luaNode.mapdata then | |||
-- 兼容老格式 | |||
self.obstacles:resize(self.TileCountX , self.TileCountY); | |||
for i , v in pairs(luaNode.mapdata) do | |||
local x = math.floor((i - 1) / self.TileCountY); | |||
local y = (i - 1) % self.TileCountY; | |||
if v == 0 then | |||
self.obstacles:setBlock(x , y , 1); | |||
else | |||
self.obstacles:setBlock(x , y , 0); | |||
end | |||
end | |||
end | |||
end | |||
function Map:saveToXmlNode(xmlNode) | |||
-- 保存tile的偏移 | |||
xmlNode.offsetX = self.OffsetX; | |||
xmlNode.offsetY = self.OffsetY; | |||
xmlNode.col = self.TileCountX; | |||
xmlNode.row = self.TileCountY; | |||
-- 保存地图宽高和Tile宽高 | |||
xmlNode.width = self.MapWidth; | |||
xmlNode.height = self.MapHeight; | |||
xmlNode.tileWidth = self.TileWidth; | |||
xmlNode.tileHeight = self.TileHeight; | |||
-- 保存障碍块 | |||
local obstaclesStr; | |||
local singleObstacleStr; | |||
-- 将障碍信息压成一个字符串 | |||
for x = 0, self.TileCountX - 1 do | |||
for y = 0, self.TileCountY - 1 do | |||
local obstacle = self:getObstacle(x, y); | |||
-- 障碍信息 | |||
if obstacle == 0 then | |||
singleObstacleStr = "1"; | |||
else | |||
singleObstacleStr = "0"; | |||
end | |||
-- 开始直接赋值,否则叠加 | |||
if obstaclesStr == nil then | |||
obstaclesStr = {singleObstacleStr}; | |||
else | |||
table.insert(obstaclesStr , "," .. singleObstacleStr); | |||
end | |||
end | |||
end | |||
xmlNode.mapdata = table.concat(obstaclesStr); | |||
end | |||
function Map:createXmlNode() | |||
local xmlNode = xml.new("map"); | |||
self:saveToXmlNode(xmlNode); | |||
return xmlNode; | |||
end | |||
-- 保存一个地图到XML文件 | |||
function Map:saveXml(fullFilePath) | |||
local xmlNode = self:createXmlNode(); | |||
xmlNode:save(fullFilePath); | |||
end | |||
-- 保存一个地图到lua文件 | |||
function Map:saveLua(fullFilePath) | |||
local luaNode = {} | |||
-- 保存tile的偏移 | |||
luaNode.offsetX = self.OffsetX; | |||
luaNode.offsetY = self.OffsetY; | |||
luaNode.col = self.TileCountX; | |||
luaNode.row = self.TileCountY; | |||
-- 保存地图宽高和Tile宽高 | |||
luaNode.width = self.MapWidth; | |||
luaNode.height = self.MapHeight; | |||
luaNode.tileWidth = self.TileWidth; | |||
luaNode.tileHeight = self.TileHeight; | |||
self.obstacles:saveToFile(fullFilePath .. ".blocks"); | |||
table.saveFile(luaNode , fullFilePath); | |||
end | |||
-- 载入一个地图文件 | |||
function Map:loadLua(luaFile) | |||
print("加载map:" , luaFile); | |||
local xmlFile = table.loadFile(luaFile); | |||
if xmlFile then | |||
self:loadFromLuaNode(xmlFile); | |||
if not xmlFile.mapdata then | |||
self.obstacles:loadFromFile(luaFile .. ".blocks"); | |||
end | |||
end | |||
print("map 加载完成"); | |||
end | |||
-- 载入一个地图文件 | |||
function Map:loadXml(nodeFile) | |||
local xmlFile = loadXmlFileWithCache(nodeFile); | |||
if xmlFile then | |||
self:loadFromXmlNode(xmlFile:find("map")); | |||
end | |||
end | |||
-- | |||
-- 获取45度A*单元格矩阵坐标 | |||
-- @param px 目标点X坐标 | |||
-- @param py 目标点Y坐标 | |||
-- @return {@link Position} 矩阵点坐标 | |||
function Map:getTilePosition(px, py) | |||
-- 界面坐标 计算以屏幕左上为原点的世界坐标 | |||
local logicalx = px / (2 * self.TileHalfWidth) + (-py) / (2 * self.TileHalfHeight) + self.OffsetX; | |||
local logicaly = px / (2 * self.TileHalfWidth) - (-py) / (2 * self.TileHalfHeight) + self.OffsetY; | |||
return cc.p(math.floor(logicalx), math.floor(logicaly)); | |||
end | |||
-- | |||
-- 获取45度A*单元格矩阵坐标(不对齐到网格) | |||
-- @param px 目标点X坐标 | |||
-- @param py 目标点Y坐标 | |||
-- @return {@link Position} 矩阵点坐标 | |||
function Map:_getTilePosition(px, py) | |||
-- 界面坐标 计算以屏幕左上为原点的世界坐标 | |||
local logicalx = px / (2 * self.TileHalfWidth) + (-py) / (2 * self.TileHalfHeight) + self.OffsetX; | |||
local logicaly = px / (2 * self.TileHalfWidth) - (-py) / (2 * self.TileHalfHeight) + self.OffsetY; | |||
return cc.p(logicalx, logicaly); | |||
end | |||
-- | |||
-- 获取45度A*单元格矩阵坐标转舞台从标(获得的是格子的中心点坐标) | |||
-- @param px 舞台X坐标 | |||
-- @param py 舞台Y坐标 | |||
-- @return {@link Position} 矩阵点坐标 | |||
function Map:getPixelPosition(tileX, tileY) | |||
local nOffX = tileX - self.OffsetX; | |||
local nOffY = tileY - self.OffsetY; | |||
local positionX = nOffX * self.TileHalfWidth + nOffY * self.TileHalfWidth; -- 斜坐标 x每加1 竖坐标x+1/2 y+1/2 | |||
local positionY = nOffX * self.TileHalfHeight - nOffY * self.TileHalfHeight; -- 斜坐标 y每加1 竖坐标x+1/2 y-1/2 | |||
return cc.p(positionX, -positionY); | |||
end | |||
-- 载入场景文件 | |||
function loadScene(nodeFile) | |||
print("加载场景" , nodeFile); | |||
TimeSpan:enterSpan("loadScene" .. nodeFile); | |||
TimeSpan:enterSpan("createNodeFromFile"); | |||
print("加载模型"); | |||
LoadingScene = true; | |||
local node = cc.StreamObject:loadFromFile(nodeFile); | |||
LoadingScene = false; | |||
node:setCollectAnimationClip(false); | |||
TimeSpan:leaveSpan(); | |||
if not EditorMode then | |||
-- 普通模式,屏蔽掉HD内容 | |||
local hd = node:findNode("HD"); | |||
if hd then | |||
local function onQualityChanged(key , value) | |||
-- 高质量 | |||
hd:setVisible(value == 1); | |||
end | |||
hd:bind(app.systemSetting.info , "graphicQuality" , onQualityChanged); | |||
end | |||
end | |||
-- 创建一个题图载入资源 | |||
TimeSpan:enterSpan("requireMap"); | |||
print("加载障碍块"); | |||
local map = require("luaScript.Map.Map"):new(); | |||
local arr = string.split(nodeFile, "."); | |||
map:loadLua(arr[1] .. ".lmap"); | |||
TimeSpan:leaveSpan(); | |||
TimeSpan:leaveSpan(); | |||
return node , map; | |||
end | |||
return Map; |
@@ -0,0 +1,133 @@ | |||
return function(Map) | |||
-- 创建地图菱形网格 | |||
function Map:createGridNode() | |||
local vertexFormat = {}; | |||
table.insert(vertexFormat , {size = 3 , usage = cc.VertexFormatUsage.POSITION}); | |||
table.insert(vertexFormat , {size = 4 , usage = cc.VertexFormatUsage.COLOR}); | |||
local vertices = ManualVertices:new(vertexFormat); | |||
vertices:setColor(cc.c4f(0,0,1,0.5)); | |||
-- 画菱形 | |||
-- 画横轴 | |||
for x = 0, self.TileCountX do | |||
local begin_ = self:getPixelPosition(x,0); | |||
local end_ = self:getPixelPosition(x,self.TileCountY); | |||
vertices:drawLine(cc.vec3(begin_.x , 0 , begin_.y) , cc.vec3(end_.x , 0 , end_.y)) | |||
end | |||
-- 画纵轴 | |||
for y = 0, self.TileCountY do | |||
local begin_ = self:getPixelPosition(0,y); | |||
local end_ = self:getPixelPosition(self.TileCountX,y); | |||
vertices:drawLine(cc.vec3(begin_.x , 0 , begin_.y) , cc.vec3(end_.x , 0 , end_.y)) | |||
end | |||
-- 画一个矩形 | |||
vertices:drawLine(cc.vec3(0,0,0), cc.vec3(self.MapWidth,0,0)); | |||
vertices:drawLine(cc.vec3(self.MapWidth,0,0), cc.vec3(self.MapWidth,0, -self.MapHeight)); | |||
vertices:drawLine(cc.vec3(self.MapWidth,0, -self.MapHeight), cc.vec3(0,0,-self.MapHeight)); | |||
vertices:drawLine(cc.vec3(0,0,0), cc.vec3(0,0,-self.MapHeight)); | |||
local mesh = cc.Mesh:createMesh(vertexFormat , vertices:getVertexCount()); | |||
mesh:setPrimitiveType(cc.PrimitiveType.LINES); | |||
mesh:setVertexData(vertices:getVertices() , 0 , vertices:getVertexCount()); | |||
mesh:setBoundingBox(vertices:getBoundingBox()); | |||
local model = cc.Model:create(mesh); | |||
local material = cc.Material:create("preload/shaders/ccDefault.material#ShaderPositionColor3D"); | |||
material:setParameterAutoBinding("CC_MVPMatrix" , "WORLD_VIEW_PROJECTION_MATRIX"); | |||
model:setMaterialPointer(material); | |||
local node = cc.Node3D:create(); | |||
node:addComponent(model); | |||
return node; | |||
end | |||
-- 创建网格上的文本 | |||
function Map:createTextNode() | |||
local node = cc.Node:create(); | |||
-- 横轴 | |||
for x = 0, self.TileCountX do | |||
-- 纵轴 | |||
for y = 0, self.TileCountY do | |||
local pos = self:getPixelPosition(x,y); | |||
local debugLabel = cc.Text:createNode(); | |||
debugLabel:setDefaults(); | |||
local config = debugLabel:getFontConfig(); | |||
config.fontSize = 12; | |||
debugLabel:setFontConfig(config); | |||
debugLabel:setAnchorPoint(cc.p(0.5,0.5)); | |||
debugLabel:setTranslation(pos.x , 0 , pos.y); | |||
debugLabel:setEulerRotation(-90,0,0); | |||
debugLabel:setScale(0.03); | |||
-- TODO这里需要显示逻辑坐标就可以了 | |||
debugLabel:setText(tostring(x) .. "," .. tostring(y)); | |||
node:addChild(debugLabel); | |||
end | |||
end | |||
return node; | |||
end | |||
-- 创建障碍块和可见区域 | |||
function Map:createObstacleNode() | |||
local node = cc.Node3D:create(); | |||
-- 画障碍块 | |||
local vertexFormat = {}; | |||
table.insert(vertexFormat , {size = 3 , usage = cc.VertexFormatUsage.POSITION}); | |||
table.insert(vertexFormat , {size = 4 , usage = cc.VertexFormatUsage.COLOR}); | |||
local material = cc.Material:create("preload/shaders/ccDefault.material#ShaderPositionColor3D"); | |||
material:setParameterAutoBinding("CC_MVPMatrix" , "WORLD_VIEW_PROJECTION_MATRIX"); | |||
local mesh = cc.MeshBatch:create(vertexFormat , cc.PrimitiveType.TRIANGLES , material , false); | |||
node:addComponent(mesh); | |||
local function drawOb(vertices , x , y) | |||
local leftTop = self:getPixelPosition(x,y); | |||
local rightTop = self:getPixelPosition(x + 1,y); | |||
local leftBottom = self:getPixelPosition(x,y + 1); | |||
local rightBottom = self:getPixelPosition(x + 1,y + 1); | |||
vertices:drawRect(cc.vec3(leftTop.x , 0 , leftTop.y) | |||
, cc.vec3(rightTop.x , 0 , rightTop.y) | |||
, cc.vec3(leftBottom.x , 0 , leftBottom.y) | |||
, cc.vec3(rightBottom.x , 0 , rightBottom.y)); | |||
end | |||
-- 更新障碍块的顶点信息 | |||
local function updateObstacle() | |||
local vertices = ManualVertices:new(vertexFormat); | |||
local x , y; | |||
-- 画障碍块 | |||
for y = 0 , self.TileCountY - 1 do | |||
for x = 0 , self.TileCountX - 1 do | |||
if self.obstacles:isBlock(x,y) then | |||
vertices:setColor(cc.c4f(1,1,0,1)); | |||
else | |||
vertices:setColor(cc.c4f(0,0,0,0)); | |||
end | |||
drawOb(vertices , x , y); | |||
end | |||
end | |||
mesh:start(); | |||
mesh:add(vertices:getVertices() , vertices:getVertexCount()); | |||
mesh:finish(); | |||
end | |||
-- 更新一个障碍块 | |||
local function updateOne(x , y , val) | |||
local vertices = ManualVertices:new(vertexFormat); | |||
if val ~= Map.ObstacleType.ObstacleNone then | |||
vertices:setColor(cc.c4f(1,1,0,1)); | |||
else | |||
vertices:setColor(cc.c4f(0,0,0,0)); | |||
end | |||
drawOb(vertices , x , y); | |||
mesh:updateVertex((self.TileCountX * y + x) * vertices:getVertexCount() , vertices:getVertexCount() , vertices:getVertices()); | |||
end | |||
self.ObstacleChanged = updateOne; | |||
updateObstacle(); | |||
return node; | |||
end | |||
end |
@@ -0,0 +1,73 @@ | |||
PKFramework={} | |||
local paths={} | |||
local files={} | |||
function PKFramework.PKImport(name,gameId) | |||
local fileName=string.gsub(name, "%.", "/") | |||
local gameConfig = getSubGameConfig(gameId or app.gameId) | |||
local rootName=gameConfig.rootName | |||
local newFileName=string.gsub(fileName, "PK", gameConfig.fileName) | |||
newFileName=string.gsub(newFileName, "pk_base", rootName) | |||
local newName=string.gsub(name, "PK", gameConfig.fileName) | |||
newName=string.gsub(newName, "pk_base", rootName) | |||
local luaFile = newFileName..".lua" | |||
local luacFile = newFileName..".luac" | |||
local isFileExist = cc.FileUtils:getInstance():isFileExist(luacFile) | |||
if not isFileExist then | |||
isFileExist = cc.FileUtils:getInstance():isFileExist(luaFile) | |||
end | |||
if isFileExist then | |||
name=newName | |||
end | |||
files[name]=true | |||
print("PKImport:"..name) | |||
return require(name) | |||
end | |||
function PKFramework.ImportWanFa(name,gameId) | |||
local fileName=string.gsub(name, "%.", "/") | |||
local gameConfig = getSubGameConfig(gameId or app.gameId) | |||
local rootName=gameConfig.rootName | |||
local newFileName=string.gsub(fileName, "PK", gameConfig.fileName) | |||
local newName=string.gsub(name, "PK", gameConfig.fileName) | |||
local luaFile = newFileName..".lua" | |||
local luacFile = newFileName..".luac" | |||
local isFileExist = cc.FileUtils:getInstance():isFileExist(luacFile) | |||
if not isFileExist then | |||
isFileExist = cc.FileUtils:getInstance():isFileExist(luaFile) | |||
end | |||
if isFileExist then | |||
name=newName | |||
end | |||
print("ImportWanFa:"..name) | |||
files[name]=true | |||
return require(name) | |||
end | |||
function PKFramework.Clean() | |||
for fileName,v in pairs(files) do | |||
print("Clean:"..fileName) | |||
package.loaded[fileName] = nil | |||
end | |||
files={} | |||
end | |||
function PKFramework.PKFrameworkClassImprot(name) | |||
print("PKFrameworkClassImprot:"..name) | |||
files[name]=true | |||
return require(name) | |||
end |
@@ -0,0 +1,50 @@ | |||
local PluginBase = require("luaScript.Plugins.PluginBase") | |||
local PluginAndroidDowloadManager = class("PluginAndroidDowloadManager" , PluginBase) | |||
function PluginAndroidDowloadManager:ctor() | |||
PluginAndroidDowloadManager.super.ctor(self); | |||
self.AndroidDowloadManager= nil | |||
end | |||
-- 启动插件 | |||
function PluginAndroidDowloadManager:start() | |||
log("PluginAndroidDowloadManager::start()") | |||
self.AndroidDowloadManager = cc.PluginManager:getInstance():createPlugin("DownloaderManager" , "com/ddgame/plugin/DownloaderManager"); | |||
if self.AndroidDowloadManager then | |||
local developerInfo = | |||
{ | |||
timeoutInSeconds = 3, | |||
tempFileNameSufix = ".temp", | |||
countOfMaxProcessingTasks = 8, | |||
}; | |||
self.AndroidDowloadManager:callVoid("initPlugin", developerInfo); | |||
end | |||
end | |||
-- 停止插件 | |||
function PluginAndroidDowloadManager:stop() | |||
if self.AndroidDowloadManager then | |||
cc.PluginManager:getInstance():removePlugin(self.AndroidDowloadManager); | |||
self.AndroidDowloadManager = nil; | |||
end | |||
end | |||
function PluginAndroidDowloadManager:createTask(url,path,onFinish,onProgress) | |||
if self.AndroidDowloadManager then | |||
local task = | |||
{ | |||
url, | |||
path, | |||
onFinish, | |||
onProgress, | |||
}; | |||
dump(task) | |||
self.AndroidDowloadManager:callMemberMethod("createTask","(Ljava/lang/String;Ljava/lang/String;II)V",task) | |||
end | |||
end | |||
return PluginAndroidDowloadManager |
@@ -0,0 +1,160 @@ | |||
local PluginBase = require("luaScript.Plugins.PluginBase") | |||
local PluginAndroidGVoice = class("PluginAndroidGVoice" , PluginBase) | |||
function PluginAndroidGVoice:ctor() | |||
PluginAndroidGVoice.super.ctor(self); | |||
self.PluginGVoice = nil | |||
end | |||
-- 启动插件 | |||
function PluginAndroidGVoice:start() | |||
log("PluginAndroidGVoice::start()") | |||
local pathRecording = cc.FileUtils:getInstance():getWritablePath().."recording.dat"; | |||
local pathDownload = cc.FileUtils:getInstance():getWritablePath().."download.dat"; | |||
self.PluginGVoice = cc.PluginManager:getInstance():createPlugin("PluginGVoice" , "com/ddgame/plugin/PluginGVoice"); | |||
if self.PluginGVoice then | |||
log("PluginAndroidGVoice::start() uid = "..table.tostring(app.user.loginInfo)) | |||
local developerInfo = | |||
{ | |||
gameId = "1574117261", | |||
userId = app.user.loginInfo.uid, | |||
gameKey = "38f5cb922398d2569b25afe577b26d78", | |||
callback = handler(self, self.onResult), -- 回调函数 | |||
pathRecording = pathRecording, | |||
pathDownload = pathDownload, | |||
}; | |||
log("PluginAndroidGVoice::start() developerInfo = ", table.tostring(developerInfo)) | |||
self.PluginGVoice:callVoid("initPlugin", developerInfo); | |||
else | |||
log("PluginAndroidGVoice::start() failed") | |||
end | |||
end | |||
-- 停止插件 | |||
function PluginAndroidGVoice:stop() | |||
if self.PluginGVoice then | |||
cc.PluginManager:getInstance():removePlugin(self.PluginGVoice); | |||
self.PluginGVoice = nil; | |||
end | |||
end | |||
-- 开始录音 | |||
function PluginAndroidGVoice:startRecord() | |||
if self.PluginGVoice then | |||
self.PluginGVoice:callVoid("startRecord"); | |||
end | |||
end | |||
-- 取消录音 | |||
function PluginAndroidGVoice:cancelRecord() | |||
if self.PluginGVoice then | |||
self.PluginGVoice:callVoid("cancelRecord"); | |||
end | |||
end | |||
-- 结束录音 | |||
function PluginAndroidGVoice:stopRecord() | |||
log("PluginAndroidGVoice:stopRecord()"); | |||
if self.PluginGVoice then | |||
self.PluginGVoice:callVoid("stopRecord"); | |||
end | |||
end | |||
-- 播放录音 | |||
function PluginAndroidGVoice:playRecord(filePath) | |||
log("PluginAndroidGVoice:playRecord() filePath = ", filePath); | |||
-- 记录回调 | |||
if self.PluginGVoice then | |||
local data = | |||
{ | |||
filePath = tostring(filePath) | |||
} | |||
log("PluginAndroidGVoice:playRecord() data = ", table.tostring(data)) | |||
self.PluginGVoice:callVoid("playRecord", data); | |||
end | |||
end | |||
-- 停止播放录音 | |||
function PluginAndroidGVoice:stopPlayRecord() | |||
log("PluginAndroidGVoice:stopPlayRecord() "); | |||
if self.PluginGVoice then | |||
self.PluginGVoice:callVoid("stopPlayRecord"); | |||
end | |||
end | |||
-- 下载录音 | |||
function PluginAndroidGVoice:downloadRecord(nfileID, nUserId, filePath, downloadCallback) | |||
self.downloadCallback = downloadCallback | |||
if self.PluginGVoice then | |||
local data = | |||
{ | |||
recordFileID = tostring(nfileID), | |||
recordTag = tostring(nUserId), | |||
filePath = tostring(filePath), | |||
play = true, | |||
} | |||
log("PluginAndroidGVoice:downloadRecord() data = ", table.tostring(data)) | |||
self.PluginGVoice:callVoid("downloadRecord", data); | |||
end | |||
end | |||
-- 回调函数 | |||
function PluginAndroidGVoice:onResult(result) | |||
log("PluginAndroidGVoice:onResult() result = ", result) | |||
local resultJson = json.decode(result); | |||
log("PluginAndroidGVoice:onResult() resultJson = ", table.tostring(resultJson)) | |||
local code = resultJson.code; | |||
local msg = resultJson.message; | |||
if code == 7001 then -- 初始化成功 | |||
--showTooltip("呀呀语音 初始化成功") | |||
local info = json.decode(msg) | |||
print("初始化成功", "info = ", table.tostring(info)) | |||
elseif code == 7002 then -- 初始化失败 | |||
--showTooltip("呀呀语音 初始化失败") | |||
local info = json.decode(msg) | |||
print("初始化失败", "info = ", table.tostring(info)) | |||
elseif code == 7003 then -- 录音成功 | |||
--showTooltip("呀呀语音 录音成功") | |||
local info = json.decode(msg) | |||
print("录音成功", "info = ", table.tostring(info)) | |||
app:dispatchEvent({name = "recordCallback", fileID = info.fileID, filePath = info.filePath, recordTime = info.recordTime }); | |||
elseif code == 7004 then -- 录音失败 | |||
--showTooltip("呀呀语音 录音失败") | |||
local info = json.decode(msg) | |||
print("录音失败", "info = ", table.tostring(info)) | |||
elseif code == 7005 then -- 录音下载成功 | |||
--showTooltip("呀呀语音 录音下载成功") | |||
local info = json.decode(msg) | |||
print("录音下载成功", "info = ", table.tostring(info)) | |||
if self.downloadCallback then | |||
self.downloadCallback(info.recordTag, info.filePath); | |||
end | |||
elseif code == 7006 then -- 录音下载失败 | |||
--showTooltip("呀呀语音 录音下载失败") | |||
local info = json.decode(msg) | |||
print("录音下载失败", "info = ", table.tostring(info)) | |||
end | |||
end | |||
return PluginAndroidGVoice |
@@ -0,0 +1,416 @@ | |||
local PluginBase = require("luaScript.Plugins.PluginBase") | |||
--[[ | |||
创建插件时更新一次定位信息 | |||
每次从后台切换回来,检查GPS开启状态,如果跟之前的状态不一样,则重新获取定位信息 | |||
--]] | |||
-- 获取玩家定位信息 | |||
local PluginAndroidLocation = class("PluginAndroidLocation" , PluginBase) | |||
function PluginAndroidLocation:ctor() | |||
PluginAndroidLocation.super.ctor(self); | |||
self.x = 0; -- 坐标x(单位米) | |||
self.y = 0; -- 坐标y(单位米) | |||
self.latitude = 0; -- 维度 | |||
self.longitude = 0; -- 经度 | |||
self.addr = "" -- 地址 | |||
self.desc = "" -- 描述 | |||
self.gpsStatus = 0; -- 最新的GPS开启状态 | |||
self.lastGpsStatus = 0; -- 上一次记录的GPS开启状态 | |||
self.timeLastUpdate = 0 | |||
self.timeDelta = 600; -- 秒 | |||
self.plugin = nil; | |||
-- 每次从后台切换回来都获取当期的GPS开启状态 | |||
app:addEventListener("applicationWillEnterForeground", handler(self, self.checkLocationEnable)); | |||
end | |||
function PluginAndroidLocation:start() | |||
self.plugin = cc.PluginManager:getInstance():createPlugin("PluginLocation" , "com/ddgame/plugin/LocationManager"); | |||
self:checkLocationEnable(); | |||
end | |||
--[[ | |||
GpsStatus = | |||
{ | |||
close = 0, --// 未开启 | |||
undeal = 1, --// 未处理 | |||
enable = 2, --// 允许 | |||
disEnable = 3, --// 拒绝的 | |||
} | |||
--]] | |||
function PluginAndroidLocation:getGpsStatus(gpsEnable) | |||
if gpsEnable then | |||
-- if self:isHavePermission() then | |||
return 2 | |||
-- else | |||
-- return 1 | |||
-- end | |||
else | |||
return 0 | |||
end | |||
end | |||
-- 重置GPS数据 | |||
function PluginAndroidLocation:resetLocationInfo() | |||
self.x = 0; | |||
self.y = 0; | |||
self.latitude = 0; | |||
self.longitude = 0 | |||
self.gpsStatus = GpsStatus.close | |||
self.lastGpsStatus = GpsStatus.close | |||
end | |||
-- 获取GPS信息 | |||
function PluginAndroidLocation:getLocationInfo() | |||
local tt = | |||
{ | |||
x = self.x, | |||
y = self.y, | |||
gpsStatus = self.gpsStatus, | |||
addr = self.addr, | |||
} | |||
logD("PluginAndroidLocation:getLocationInfo() tt = ", table.tostring(tt)) | |||
return tt; | |||
end | |||
--获取定位服务开启状态 | |||
function PluginAndroidLocation:getLocationEnable() | |||
logD("PluginAndroidLocation:getLocationEnable()"); | |||
if self.plugin then | |||
local locationEnable = self.plugin:callBool("getLocationServicesEnabled"); | |||
logD("PluginAndroidLocation:getLocationEnable() locationEnable = ", locationEnable); | |||
return locationEnable; | |||
end | |||
return false | |||
end | |||
--是否开启定位权限 | |||
function PluginAndroidLocation:isHavePermission() | |||
if self.plugin then | |||
local locationEnable = self.plugin:callBool("isHavePermission"); | |||
logD("PluginAndroidLocation:isHavePermission = ", locationEnable); | |||
return locationEnable; | |||
end | |||
return false | |||
end | |||
-- 前往GPS设置界面 | |||
function PluginAndroidLocation:gotoGpsSettingView() | |||
logD("PluginAndroidLocation:gotoGpsSettingView()"); | |||
if self.plugin then | |||
logD("PluginAndroidLocation:gotoGpsSettingView()"); | |||
local state = self.plugin:callVoid("gotoGpsSettingView"); | |||
end | |||
end | |||
-- 前往APP权限界面 | |||
function PluginAndroidLocation:gotoAppPermissionsView() | |||
logD("PluginAndroidLocation:gotoAppPermissionsView()"); | |||
if self.plugin then | |||
logD("PluginAndroidLocation:gotoAppPermissionsView()"); | |||
local state = self.plugin:callVoid("gotoAppPermissionsView"); | |||
end | |||
end | |||
-- 前往打开GPS | |||
function PluginAndroidLocation:openGPS() | |||
local locationEnable = self:getLocationEnable() | |||
if locationEnable then | |||
self:gotoAppPermissionsView() | |||
else | |||
self:gotoGpsSettingView() | |||
end | |||
end | |||
-- 每次从后台切换回来都获取当期的GPS开启状态 | |||
-- 如果本次的状态跟上一次不一样,则更新数据 | |||
function PluginAndroidLocation:checkLocationEnable() | |||
logD("PluginAndroidLocation:checkLocationEnable()"); | |||
local gpsEnable = self:getLocationEnable() | |||
logD("PluginAndroidLocation:checkLocationEnable(), gpsEnable = ", gpsEnable) | |||
self.gpsStatus = self:getGpsStatus(gpsEnable) | |||
logD("PluginAndroidLocation:checkLocationEnable(), self.gpsStatus = ", self.gpsStatus) | |||
-- logD("PluginAndroidLocation:checkLocationEnable(), self.lastGpsStatus = ", self.lastGpsStatus); | |||
-- self:updateLocation() | |||
if self.gpsStatus == GpsStatus.enable then | |||
-- 当前是开启的 | |||
if self.lastGpsStatus ~= self.gpsStatus then | |||
self:updateLocation() | |||
else | |||
local timeNow = os.time() | |||
if timeNow - self.timeLastUpdate > self.timeDelta then | |||
self:updateLocation() | |||
end | |||
end | |||
else | |||
-- 重置数据 | |||
self:resetLocationInfo() | |||
self:onGpsInoChanged() | |||
end | |||
self.lastGpsStatus = self.gpsStatus | |||
end | |||
-- 更新 GPS 位置信息 | |||
function PluginAndroidLocation:updateLocation() | |||
-- local timeNow = os.time() | |||
-- if timeNow - self.timeLastUpdate < self.timeDelta then | |||
-- return | |||
-- end | |||
logD("PluginAndroidLocation:updateLocation()"); | |||
if self.plugin then | |||
local params = | |||
{ | |||
callback = handler(self, self.onResult); -- 回调函数 | |||
}; | |||
self.plugin:callVoid("start", params); | |||
end | |||
end | |||
-- 回调函数 | |||
-- function PluginAndroidLocation:onResult(result) | |||
-- logD("PluginAndroidLocation:onResult() result = ", tostring(result)) | |||
-- local jsonRet = json.decode(result); | |||
-- if not jsonRet then | |||
-- logD("PluginAndroidLocation:onResult() jsonRet is nil ") | |||
-- self:resetLocationInfo() | |||
-- self:onGpsInoChanged() | |||
-- return | |||
-- end | |||
-- if not jsonRet.code or jsonRet.code ~= 0 then | |||
-- logD("PluginAndroidLocation:onResult() jsonRet.code = ", jsonRet.code) | |||
-- self:resetLocationInfo() | |||
-- self:onGpsInoChanged() | |||
-- return | |||
-- end | |||
-- local jsonData = json.decode(jsonRet.message or "") | |||
-- if not jsonData then | |||
-- logD("PluginAndroidLocation:onResult() jsonData is nil ") | |||
-- self:resetLocationInfo() | |||
-- self:onGpsInoChanged() | |||
-- return | |||
-- end | |||
-- --[[ | |||
-- message.put("locType", locType); // 定位结果类型 | |||
-- message.put("latitude", latitude); // 纬度 | |||
-- message.put("longitude", longitude); // 经度 | |||
-- message.put("radius", radius); // 经度 | |||
-- message.put("addr", addr); // 地址 | |||
-- message.put("desc", desc); // 地址描述 | |||
-- --]] | |||
-- local locType = jsonData.locType; | |||
-- if locType ~= 61 and locType ~= 66 and locType ~= 161 then | |||
-- logD("PluginAndroidLocation:onResult() 定位失败 locType = ", locType) | |||
-- self:resetLocationInfo() | |||
-- self:onGpsInoChanged() | |||
-- return | |||
-- end | |||
-- local latitude = jsonData.latitude | |||
-- local longitude = jsonData.longitude | |||
-- local addr = jsonData.addr | |||
-- local desc = jsonData.desc | |||
-- -- 如果本地地位的数据和上一次一样,就没有必要进行转换了 | |||
-- if latitude == self.latitude and longitude == self.longitude then | |||
-- logD("PluginAndroidLocation:onResult() 定位数据和上次的一样,不需要转换") | |||
-- self:onGpsInoChanged() | |||
-- return | |||
-- end | |||
-- -- 转换坐标 | |||
-- local baiduApi = "http://api.map.baidu.com/geoconv/v1/"; | |||
-- local params = | |||
-- { | |||
-- coords = tostring(longitude)..","..tostring(latitude), | |||
-- from = 5, | |||
-- to = 6, | |||
-- ak = "w7567NEaAFO4f5QDf6KphFVdeNUmAlWK", | |||
-- mcode = "7F:3E:A9:0C:CC:03:87:9B:26:DF:CC:BD:E6:A4:DD:C2:76:F6:2A:76;com.dingdinggame.huanle" | |||
-- } | |||
-- httpPost(baiduApi, params, function(status, response) | |||
-- --[[ | |||
-- {"status":0,"result":[{"x":113.8627303666,"y":22.580960414847}]} | |||
-- ]] | |||
-- logD("PluginAndroidLocation:onHttpResponse() status = ", tostring(status), tostring(response)) | |||
-- if status ~= "successed" then | |||
-- logD("PluginAndroidLocation:onHttpResponse() status = ", status) | |||
-- self:onGpsInoChanged() | |||
-- return | |||
-- end | |||
-- local ttRet = json.decode(response) | |||
-- logD("PluginAndroidLocation:onHttpResponse() ttRet = ", table.tostring(ttRet)) | |||
-- if tonumber(ttRet.status) ~= 0 then | |||
-- logD("PluginAndroidLocation:onHttpResponse() 转换米制坐标失败") | |||
-- self:onGpsInoChanged() | |||
-- return | |||
-- end | |||
-- local x = ttRet.result[1].x; | |||
-- local y = ttRet.result[1].y; | |||
-- -- 转换成功之后记录数据 | |||
-- self.x = x; | |||
-- self.y = y; | |||
-- self.addr = addr | |||
-- self.desc = desc | |||
-- self.latitude = latitude | |||
-- self.longitude = longitude | |||
-- -- 记录更新成功的时间 | |||
-- self.timeLastUpdate = os.time() | |||
-- -- 发送事件 | |||
-- self:onGpsInoChanged() | |||
-- end) | |||
-- end | |||
function PluginAndroidLocation:onResult(result) | |||
logD("PluginAndroidLocation:onResult() result = ", tostring(result)) | |||
local jsonRet = json.decode(result); | |||
if not jsonRet then | |||
logD("PluginAndroidLocation:onResult() jsonRet is nil ") | |||
self:resetLocationInfo() | |||
self:onGpsInoChanged() | |||
return | |||
end | |||
if not jsonRet.code or jsonRet.code ~= 0 then | |||
logD("PluginAndroidLocation:onResult() jsonRet.code = ", jsonRet.code) | |||
self:resetLocationInfo() | |||
self:onGpsInoChanged() | |||
return | |||
end | |||
local jsonData = json.decode(jsonRet.message or "") | |||
if not jsonData then | |||
logD("PluginAndroidLocation:onResult() jsonData is nil ") | |||
self:resetLocationInfo() | |||
self:onGpsInoChanged() | |||
return | |||
end | |||
--[[ | |||
message.put("locType", locType); // 定位结果类型 | |||
message.put("latitude", latitude); // 纬度 | |||
message.put("longitude", longitude); // 经度 | |||
message.put("radius", radius); // 经度 | |||
message.put("addr", addr); // 地址 | |||
message.put("desc", desc); // 地址描述 | |||
--]] | |||
local locType = jsonData.locType; | |||
if locType ~= 0 then--61 and locType ~= 66 and locType ~= 161 then | |||
logD("PluginAndroidLocation:onResult() 定位失败 locType = ", locType) | |||
self:resetLocationInfo() | |||
if locType == 12 then | |||
self.gpsStatus = GpsStatus.disEnable | |||
else | |||
self.gpsStatus = GpsStatus.close | |||
end | |||
self:onGpsInoChanged() | |||
return | |||
end | |||
-- 记录更新成功的时间 | |||
self.timeLastUpdate = os.time() | |||
local latitude = jsonData.latitude | |||
local longitude = jsonData.longitude | |||
local addr = jsonData.addr | |||
local desc = jsonData.desc | |||
-- 如果本地地位的数据和上一次一样,就没有必要进行转换了 | |||
if latitude == self.latitude and longitude == self.longitude then | |||
logD("PluginAndroidLocation:onResult() 定位数据和上次的一样,不需要转换") | |||
self:onGpsInoChanged() | |||
return | |||
end | |||
self.x = latitude; | |||
self.y = longitude; | |||
self.addr = addr | |||
self.desc = desc | |||
self.latitude = latitude | |||
self.longitude = longitude | |||
-- 发送事件 | |||
self:onGpsInoChanged() | |||
-- 转换坐标 | |||
-- local baiduApi = "http://api.map.baidu.com/geoconv/v1/"; | |||
-- local params = | |||
-- { | |||
-- coords = tostring(longitude)..","..tostring(latitude), | |||
-- from = 5, | |||
-- to = 6, | |||
-- ak = "0ucQuyttiZfCGqwHjtj87kLwkcUI81Fz", | |||
-- mcode = "D4:63:2B:28:DE:42:63:2E:99:6D:6D:5E:23:C3:51:C0:BB:50:AA:C4;com.dingdinggame.bohu" | |||
-- } | |||
-- httpPost(baiduApi, params, function(status, response) | |||
-- --[[ | |||
-- {"status":0,"result":[{"x":113.8627303666,"y":22.580960414847}]} | |||
-- ]] | |||
-- logD("PluginAndroidLocation:onHttpResponse() status = ", tostring(status), tostring(response)) | |||
-- if status ~= "successed" then | |||
-- logD("PluginAndroidLocation:onHttpResponse() status = ", status) | |||
-- self:onGpsInoChanged() | |||
-- return | |||
-- end | |||
-- local ttRet = json.decode(response) | |||
-- logD("PluginAndroidLocation:onHttpResponse() ttRet = ", table.tostring(ttRet)) | |||
-- if tonumber(ttRet.status) ~= 0 then | |||
-- logD("PluginAndroidLocation:onHttpResponse() 转换米制坐标失败") | |||
-- self:onGpsInoChanged() | |||
-- return | |||
-- end | |||
-- local x = ttRet.result[1].x; | |||
-- local y = ttRet.result[1].y; | |||
-- -- 转换成功之后记录数据 | |||
-- self.x = x; | |||
-- self.y = y; | |||
-- self.addr = addr | |||
-- self.desc = desc | |||
-- self.latitude = latitude | |||
-- self.longitude = longitude | |||
-- -- 记录更新成功的时间 | |||
-- self.timeLastUpdate = os.time() | |||
-- -- 发送事件 | |||
-- self:onGpsInoChanged() | |||
-- end) | |||
end | |||
-- 发送通知 - 定位完成 | |||
function PluginAndroidLocation:onGpsInoChanged() | |||
logD("PluginAndroidLocation:onGpsInoChanged()") | |||
local ttGpsInfo = self:getLocationInfo() | |||
app.user:updateGpsInfo(ttGpsInfo) | |||
app:dispatchEvent({name = "onGpsInoChanged"}) | |||
end | |||
return PluginAndroidLocation |
@@ -0,0 +1,55 @@ | |||
local PluginBase = require("luaScript.Plugins.PluginBase") | |||
local PluginAndroidPing = class("PluginAndroidPing" , PluginBase) | |||
function PluginAndroidPing:ctor() | |||
PluginAndroidPing.super.ctor(self); | |||
self.AndroidPing= nil | |||
end | |||
-- 启动插件 | |||
function PluginAndroidPing:start() | |||
log("PluginAndroidPing::start()") | |||
self.AndroidPing = cc.PluginManager:getInstance():createPlugin("PluginPing" , "com/ddgame/plugin/PluginPing"); | |||
if self.AndroidPing then | |||
local developerInfo = | |||
{ | |||
pingTime = 5000, --多久ping一次 毫秒 | |||
}; | |||
self.AndroidPing:callVoid("initPlugin", developerInfo); | |||
end | |||
end | |||
-- 停止插件 | |||
function PluginAndroidPing:stop() | |||
if self.AndroidPing then | |||
cc.PluginManager:getInstance():removePlugin(self.AndroidPing); | |||
self.AndroidPing = nil; | |||
end | |||
end | |||
function PluginAndroidPing:startPing() | |||
if self.AndroidPing then | |||
self.AndroidPing:callVoid("startPing") | |||
end | |||
end | |||
function PluginAndroidPing:stopPing() | |||
if self.AndroidPing then | |||
self.AndroidPing:callVoid("stopPing") | |||
end | |||
end | |||
function PluginAndroidPing:getPing() | |||
if self.AndroidPing then | |||
return self.AndroidPing:callInt("getPing") | |||
end | |||
return 0 | |||
end | |||
return PluginAndroidPing |
@@ -0,0 +1,68 @@ | |||
-- 基类 | |||
local PluginBase = class("PluginBase") | |||
PluginBase.Code = | |||
{ | |||
OP_LOG = 101, | |||
OP_PASTE = 102, | |||
--// 初始化状态int | |||
INIT = 1000, | |||
INIT_SUCCESS = 1001, | |||
INIT_FAIL = 1002, | |||
--// 登录状态码 | |||
LOGIN = 2000, | |||
LOGIN_SUCCESS = 2001, | |||
LOGIN_CANCEL = 2002, | |||
LOGIN_FAIL = 2003, | |||
--// 登出状态码 | |||
LOGOUT = 3000, | |||
LOGOUT_SUCCESS = 3001, | |||
LOGOUT_CANCEL = 3002, | |||
LOGOUT_FAIL = 3003, | |||
--// 分享游戏 | |||
SHARE = 4000, | |||
SHARE_SUCCESS = 4001, | |||
SHARE_CANCEL = 4002, | |||
SHARE_FAIL = 4003, | |||
--// 支付状态码 | |||
PAY = 5000, | |||
PAY_SUCCESS = 5001, | |||
PAY_CANCEL = 5002, | |||
PAY_FAIL = 5003, | |||
PAY_TIMEOUT = 5004, | |||
PAY_EXC = 5005, | |||
PAY_WAIT_CHECK = 5006, | |||
--// 录音 | |||
RECORD = 7000, --// 录音模块 | |||
RECORD_SUCCESS = 7001, --// 录音成功 | |||
RECORD_FAIL = 7002, --// 录音失败 | |||
RECORD_DOWNLOAD_SUCCESS = 7003, --// 录音下载成功 | |||
RECORD_DOWNLOAD_FAIL = 7004, --// 录音下载失败 | |||
--// DNS解析 | |||
HTTP_DNS = 8000, | |||
HTTP_DNS_PARSE_SUCCESS = 8001, | |||
HTTP_DNS_PARSE_FAIL = 8002, | |||
} | |||
function PluginBase:ctor() | |||
end | |||
-- 启动插件 | |||
function PluginBase:start() | |||
end | |||
-- 停止插件 | |||
function PluginBase:stop() | |||
end | |||
return PluginBase |
@@ -0,0 +1,50 @@ | |||
local PluginBase = require("luaScript.Plugins.PluginBase") | |||
local PluginIosDowloadManager = class("PluginIosDowloadManager" , PluginBase) | |||
function PluginIosDowloadManager:ctor() | |||
PluginIosDowloadManager.super.ctor(self); | |||
self.IosDowloadManager= nil | |||
end | |||
-- 启动插件 | |||
function PluginIosDowloadManager:start() | |||
log("PluginIosDowloadManager::start()") | |||
self.IosDowloadManager = cc.PluginManager:getInstance():createPlugin("DownloaderManager" , "DownloaderManager"); | |||
if self.IosDowloadManager then | |||
local developerInfo = | |||
{ | |||
timeoutInSeconds = 3, | |||
tempFileNameSufix = ".temp", | |||
countOfMaxProcessingTasks = 8, | |||
}; | |||
self.IosDowloadManager:callVoid("initPlugin", developerInfo); | |||
end | |||
end | |||
-- 停止插件 | |||
function PluginIosDowloadManager:stop() | |||
if self.IosDowloadManager then | |||
cc.PluginManager:getInstance():removePlugin(self.IosDowloadManager); | |||
self.IosDowloadManager = nil; | |||
end | |||
end | |||
function PluginIosDowloadManager:createTask(url,path,onFinish,onProgress) | |||
if self.IosDowloadManager then | |||
local task = | |||
{ | |||
url, | |||
path, | |||
onFinish, | |||
onProgress, | |||
}; | |||
dump(task) | |||
self.IosDowloadManager:callMemberMethod("createTask",unpack(task)) | |||
end | |||
end | |||
return PluginIosDowloadManager |
@@ -0,0 +1,159 @@ | |||
local PluginBase = require("luaScript.Plugins.PluginBase") | |||
local PluginIosGVoice = class("PluginIosGVoice" , PluginBase) | |||
function PluginIosGVoice:ctor() | |||
PluginIosGVoice.super.ctor(self); | |||
self.PluginGVoice = nil | |||
end | |||
-- 启动插件 | |||
function PluginIosGVoice:start() | |||
log("PluginIosGVoice::start()") | |||
local pathRecording = cc.FileUtils:getInstance():getWritablePath().."recording.dat"; | |||
local pathDownload = cc.FileUtils:getInstance():getWritablePath().."download.dat"; | |||
self.PluginGVoice = cc.PluginManager:getInstance():createPlugin("IOSPluginGVoice" , "IOSPluginGVoice"); | |||
if self.PluginGVoice then | |||
log("PluginIosGVoice::start() uid = "..table.tostring(app.user.loginInfo)) | |||
local developerInfo = | |||
{ | |||
gameId = "1574117261", | |||
userId = app.user.loginInfo.uid, | |||
gameKey = "38f5cb922398d2569b25afe577b26d78", | |||
pathRecording = pathRecording, | |||
pathDownload = pathDownload, | |||
callback = handler(self, self.onResult), -- 回调函数 | |||
}; | |||
log("PluginIosGVoice::start() developerInfo = ", table.tostring(developerInfo)) | |||
self.PluginGVoice:callVoid("initPlugin", developerInfo); | |||
else | |||
log("PluginIosGVoice::start() failed") | |||
end | |||
end | |||
-- 停止插件 | |||
function PluginIosGVoice:stop() | |||
if self.PluginGVoice then | |||
cc.PluginManager:getInstance():removePlugin(self.PluginGVoice); | |||
self.PluginGVoice = nil; | |||
end | |||
end | |||
-- 开始录音 | |||
function PluginIosGVoice:startRecord() | |||
if self.PluginGVoice then | |||
self.PluginGVoice:callVoid("startRecord"); | |||
end | |||
end | |||
-- 取消录音 | |||
function PluginIosGVoice:cancelRecord() | |||
if self.PluginGVoice then | |||
self.PluginGVoice:callVoid("cancelRecord"); | |||
end | |||
end | |||
-- 结束录音 | |||
function PluginIosGVoice:stopRecord() | |||
if self.PluginGVoice then | |||
self.PluginGVoice:callVoid("stopRecord"); | |||
end | |||
end | |||
-- 播放录音 | |||
function PluginIosGVoice:playRecord(filePath) | |||
log("PluginIosGVoice:playRecord() filePath = ", filePath); | |||
-- 记录回调 | |||
if self.PluginGVoice then | |||
local data = | |||
{ | |||
filePath = tostring(filePath) | |||
} | |||
log("PluginIosGVoice:playRecord() data = ", table.tostring(data)) | |||
self.PluginGVoice:callVoid("playRecord", data); | |||
end | |||
end | |||
-- 停止播放录音 | |||
function PluginIosGVoice:stopPlayRecord() | |||
log("PluginIosGVoice:stopPlayRecord() "); | |||
if self.PluginGVoice then | |||
self.PluginGVoice:callVoid("stopPlayRecord"); | |||
end | |||
end | |||
-- 下载录音 | |||
function PluginIosGVoice:downloadRecord(nfileID, nUserId, filePath, downloadCallback) | |||
self.downloadCallback = downloadCallback | |||
if self.PluginGVoice then | |||
local data = | |||
{ | |||
recordFileID = tostring(nfileID), | |||
recordTag = tostring(nUserId), | |||
filePath = tostring(filePath), | |||
play = true, | |||
} | |||
log("PluginIosGVoice:downloadRecord() data = ", table.tostring(data)) | |||
self.PluginGVoice:callVoid("downloadRecord", data); | |||
end | |||
end | |||
-- 回调函数 | |||
function PluginIosGVoice:onResult(result) | |||
log("PluginIosGVoice:onResult() result = ", result) | |||
local resultJson = json.decode(result); | |||
log("PluginIosGVoice:onResult() resultJson = ", table.tostring(resultJson)) | |||
local code = resultJson.code; | |||
local msg = resultJson.message; | |||
if code == 7001 then -- 初始化成功 | |||
--showTooltip("呀呀语音 初始化成功") | |||
local info = json.decode(msg) | |||
print("初始化成功", "info = ", table.tostring(info)) | |||
elseif code == 7002 then -- 初始化失败 | |||
--showTooltip("呀呀语音 初始化失败") | |||
local info = json.decode(msg) | |||
print("初始化失败", "info = ", table.tostring(info)) | |||
elseif code == 7003 then -- 录音成功 | |||
--showTooltip("呀呀语音 录音成功") | |||
local info = json.decode(msg) | |||
print("录音成功", "info = ", table.tostring(info)) | |||
app:dispatchEvent({name = "recordCallback", fileID = info.fileID, filePath = info.filePath, recordTime = info.recordTime }); | |||
elseif code == 7004 then -- 录音失败 | |||
--showTooltip("呀呀语音 录音失败") | |||
local info = json.decode(msg) | |||
print("录音失败", "info = ", table.tostring(info)) | |||
elseif code == 7005 then -- 录音下载成功 | |||
--showTooltip("呀呀语音 录音下载成功") | |||
local info = json.decode(msg) | |||
print("录音下载成功", "info = ", table.tostring(info)) | |||
if self.downloadCallback then | |||
self.downloadCallback(info.recordTag, info.filePath); | |||
end | |||
elseif code == 7006 then -- 录音下载失败 | |||
--showTooltip("呀呀语音 录音下载失败") | |||
local info = json.decode(msg) | |||
print("录音下载失败", "info = ", table.tostring(info)) | |||
end | |||
end | |||
return PluginIosGVoice |
@@ -0,0 +1,330 @@ | |||
local PluginBase = require("luaScript.Plugins.PluginBase") | |||
local PluginIosLocation = class("PluginIosLocation" , PluginBase) | |||
function PluginIosLocation:ctor() | |||
PluginIosLocation.super.ctor(self); | |||
self.x = 0; -- 坐标x(单位米) | |||
self.y = 0; -- 坐标y(单位米) | |||
self.latitude = 0; -- 维度 | |||
self.longitude = 0; -- 经度 | |||
self.addr = "" -- 地址 | |||
self.desc = "" -- 描述 | |||
self.gpsStatus = 0; | |||
self.lastGpsStatus = 0; | |||
self.timeLastUpdate = 0 | |||
self.timeDelta = 600; -- 秒 | |||
self.plugin = nil; | |||
-- 每次从后台切换回来都获取当期的GPS开启状态 | |||
app:addEventListener("applicationWillEnterForeground", handler(self, self.checkLocationEnable)); | |||
end | |||
--[[ | |||
typedef NS_ENUM(int, CLAuthorizationStatus) { | |||
// 未处理 | |||
kCLAuthorizationStatusNotDetermined = 0, | |||
// 受限制的 | |||
kCLAuthorizationStatusRestricted = 1, | |||
// 已禁止 | |||
kCLAuthorizationStatusDenied = 2, | |||
// 一直允许 | |||
kCLAuthorizationStatusAuthorizedAlways = 3, | |||
// 使用时 | |||
kCLAuthorizationStatusAuthorizedWhenInUse = 4, | |||
// 已经被废弃了 | |||
kCLAuthorizationStatusAuthorized = 5 | |||
}; | |||
--]] | |||
function PluginIosLocation:start() | |||
if isReviewVersion() then | |||
return | |||
end | |||
self.plugin = cc.PluginManager:getInstance():createPlugin("PluginLocation" , "LocationManager"); | |||
self:checkLocationEnable(); | |||
end | |||
--[[ | |||
GpsStatus = | |||
{ | |||
close = 0, --// 未开启 | |||
undeal = 1, --// 未处理 | |||
enable = 2, --// 允许 | |||
disEnable = 3, --// 拒绝的 | |||
} | |||
--]] | |||
function PluginIosLocation:getGpsStatus(gpsEnable, gpsPermission) | |||
if gpsEnable then | |||
if gpsPermission == 0 then | |||
return GpsStatus.undeal | |||
elseif gpsPermission == 2 then | |||
return GpsStatus.disEnable | |||
else | |||
return GpsStatus.enable | |||
end | |||
else | |||
return GpsStatus.close | |||
end | |||
end | |||
-- 重置GPS数据 | |||
function PluginIosLocation:resetLocationInfo() | |||
self.x = 0; | |||
self.y = 0; | |||
self.latitude = 0; | |||
self.longitude = 0 | |||
self.gpsStatus = 0; | |||
self.lastGpsStatus = 0; | |||
end | |||
-- 获取GPS信息 | |||
function PluginIosLocation:getLocationInfo() | |||
local tt = | |||
{ | |||
x = self.x, | |||
y = self.y, | |||
gpsStatus = self.gpsStatus, | |||
addr = self.addr, | |||
} | |||
logD("PluginIosLocation:getLocationInfo() tt = ", table.tostring(tt)) | |||
return tt; | |||
end | |||
--获取定位状态 | |||
function PluginIosLocation:getLocationEnable() | |||
logD("PluginIosLocation:getLocationEnable()"); | |||
if self.plugin then | |||
local locationEnable = self.plugin:callBool("getLocationServicesEnabled"); | |||
logD("PluginIosLocation:getLocationEnable() locationEnable = ", locationEnable); | |||
return (locationEnable == "true"); | |||
end | |||
return false | |||
end | |||
-- 最新的GPS权限状态 | |||
function PluginIosLocation:getGpsPermission() | |||
logD("PluginIosLocation:getGpsPermission()"); | |||
if self.plugin then | |||
local gpsPermission = self.plugin:callBool("getAppLocationPermission"); | |||
logD("PluginIosLocation:getGpsPermission() gpsPermission = ", gpsPermission); | |||
return tonumber(gpsPermission); | |||
end | |||
return 0 | |||
end | |||
-- 前往GPS设置界面 | |||
function PluginIosLocation:gotoGpsSettingView() | |||
logD("PluginIosLocation:gotoGpsSettingView()"); | |||
if self.plugin then | |||
local params = | |||
{ | |||
title = "开启定位服务", | |||
message = "您的定位没有开启,请点击 设置 -> 隐私 -> 定位服务 -> 开启定位服务 -> 设置悠闲麻将欢乐允许访问位置信息", | |||
} | |||
logD("PluginIosLocation:gotoGpsSettingView()"); | |||
self.plugin:callVoid("gotoGpsSettingView", params); | |||
end | |||
end | |||
-- 前往APP权限界面 | |||
function PluginIosLocation:gotoAppPermissionsView() | |||
logD("PluginIosLocation:gotoAppPermissionsView()"); | |||
if self.plugin then | |||
logD("PluginIosLocation:gotoAppPermissionsView()"); | |||
self.plugin:callVoid("gotoAppPermissionsView"); | |||
end | |||
end | |||
-- 前往打开GPS | |||
function PluginIosLocation:openGPS() | |||
local locationEnable = self:getLocationEnable() | |||
if locationEnable then | |||
self:gotoAppPermissionsView() | |||
else | |||
self:gotoGpsSettingView() | |||
end | |||
end | |||
-- 每次从后台切换回来都获取当期的GPS开启状态 | |||
-- 如果本次的状态跟上一次不一样,则更新数据 | |||
function PluginIosLocation:checkLocationEnable() | |||
logD("PluginIosLocation:checkLocationEnable()"); | |||
local gpsEnable = self:getLocationEnable() | |||
local gpsPermission = self:getGpsPermission() | |||
logD("PluginIosLocation:checkLocationEnable(), gpsEnable = ", gpsEnable); | |||
logD("PluginIosLocation:checkLocationEnable(), gpsPermission = ", gpsPermission); | |||
self.gpsStatus = self:getGpsStatus(gpsEnable, gpsPermission); | |||
logD("PluginIosLocation:checkLocationEnable(), self.gpsStatus = ", self.gpsStatus); | |||
logD("PluginIosLocation:checkLocationEnable(), self.lastGpsStatus = ", self.lastGpsStatus); | |||
if self.gpsStatus == GpsStatus.enable then | |||
-- 当前是开启的 | |||
if self.lastGpsStatus ~= self.gpsStatus then | |||
self:updateLocation() | |||
else | |||
local timeNow = os.time() | |||
if timeNow - self.timeLastUpdate > self.timeDelta then | |||
self:updateLocation() | |||
end | |||
end | |||
else | |||
if gpsPermission == 0 then | |||
-- 未处理的情况下,还是可以请求一下的 | |||
self:updateLocation() | |||
else | |||
-- 重置数据 | |||
self:resetLocationInfo() | |||
self:onGpsInoChanged() | |||
end | |||
end | |||
self.lastGpsStatus = self.gpsStatus; | |||
end | |||
function PluginIosLocation:updateLocation() | |||
if self.plugin then | |||
local params = | |||
{ | |||
callback = handler(self, self.onResult); -- 回调函数 | |||
}; | |||
self.plugin:callVoid("start", params); | |||
end | |||
end | |||
function PluginIosLocation:stopLocation() | |||
if self.plugin then | |||
print("PluginIosLocation:stopLocation()"); | |||
self.plugin:callVoid("stop"); | |||
end | |||
end | |||
-- 回调函数 | |||
function PluginIosLocation:onResult(result) | |||
logD("PluginIosLocation:onResult() ", tostring(result)) | |||
local jsonRet = json.decode(result); | |||
if not jsonRet then | |||
logD("PluginIosLocation:onResult() jsonRet is nil ") | |||
self:onGpsInoChanged() | |||
return | |||
end | |||
if not jsonRet.code or tonumber(jsonRet.code) ~= 0 then | |||
logD("PluginIosLocation:onResult() jsonRet.code = ", jsonRet.code) | |||
self:onGpsInoChanged() | |||
return | |||
end | |||
local jsonData = json.decode(jsonRet.message or "") | |||
if not jsonData then | |||
logD("PluginIosLocation:onResult() jsonData is nil ") | |||
self:onGpsInoChanged() | |||
return | |||
end | |||
--[[ | |||
message.put("latitude", latitude); // 纬度 | |||
message.put("longitude", longitude); // 经度 | |||
message.put("radius", radius); // 经度 | |||
--]] | |||
local latitude = jsonData.latitude | |||
local longitude = jsonData.longitude | |||
local addr = jsonData.addr | |||
local desc = jsonData.desc | |||
-- 如果本地地位的数据和上一次一样,就没有必要进行转换了 | |||
if latitude == self.latitude and longitude == self.longitude then | |||
self:onGpsInoChanged() | |||
return | |||
end | |||
self.x = latitude; | |||
self.y = longitude; | |||
self.addr = addr | |||
self.desc = desc | |||
self.latitude = latitude | |||
self.longitude = longitude | |||
-- 记录更新成功的时间 | |||
self.timeLastUpdate = os.time() | |||
-- 发送事件 | |||
self:onGpsInoChanged() | |||
-- local baiduApi = "http://api.map.baidu.com/geoconv/v1/"; | |||
-- local params = | |||
-- { | |||
-- coords = tostring(longitude)..","..tostring(latitude), | |||
-- from = 1, | |||
-- to = 6, | |||
-- ak = "w7567NEaAFO4f5QDf6KphFVdeNUmAlWK", | |||
-- mcode = "7F:3E:A9:0C:CC:03:87:9B:26:DF:CC:BD:E6:A4:DD:C2:76:F6:2A:76;com.dingdinggame.huanle" | |||
-- } | |||
-- httpPost(baiduApi, params, function(status, response) | |||
-- --[[ | |||
-- {"status":0,"result":[{"x":113.8627303666,"y":22.580960414847}]} | |||
-- ]] | |||
-- logD("PluginIosLocation:onResult() status = ", tostring(status), tostring(response)) | |||
-- if status ~= "successed" then | |||
-- logD("PluginIosLocation:onResult() status = ", status) | |||
-- self:onGpsInoChanged() | |||
-- return | |||
-- end | |||
-- local ttRet = json.decode(response) | |||
-- logD("PluginIosLocation:onResult() ttRet = ", table.tostring(ttRet)) | |||
-- if tonumber(ttRet.status) ~= 0 then | |||
-- logD("PluginIosLocation:onResult() 转换米制坐标失败") | |||
-- self:onGpsInoChanged() | |||
-- return | |||
-- end | |||
-- local x = ttRet.result[1].x; | |||
-- local y = ttRet.result[1].y; | |||
-- -- 转换成功之后记录数据 | |||
-- self.x = x; | |||
-- self.y = y; | |||
-- self.addr = addr | |||
-- self.desc = desc | |||
-- self.latitude = latitude | |||
-- self.longitude = longitude | |||
-- -- 记录更新成功的时间 | |||
-- self.timeLastUpdate = os.time() | |||
-- -- 发送事件 | |||
-- self:onGpsInoChanged() | |||
-- end) | |||
end | |||
-- 发送通知 - 定位成功 | |||
function PluginIosLocation:onGpsInoChanged() | |||
logD("PluginIosLocation:onGpsInoChanged()") | |||
local ttGpsInfo = self:getLocationInfo() | |||
app.user:updateGpsInfo(ttGpsInfo) | |||
app:dispatchEvent({name = "onGpsInoChanged"}) | |||
end | |||
return PluginIosLocation |
@@ -0,0 +1,320 @@ | |||
local PluginBase = require("luaScript.Plugins.PluginBase") | |||
local PluginConfig = require("preload.PluginConfig") | |||
local PluginIosPay = class("PluginIosPay" , PluginBase) | |||
IosPayData = defClass("IosPayData" | |||
, defVar("dataStr", VT_String, "") | |||
) | |||
function PluginIosPay:ctor() | |||
PluginIosPay.super.ctor(self); | |||
self.plugin = nil | |||
--self.payData = IosPayData:new(); | |||
--self.filePath = cc.FileUtils:getInstance():getWritablePath() .. "iosPay.data"; | |||
self.payData = {} | |||
self.payDataFile = cc.FileUtils:getInstance():getWritablePath() .. "iosPay.data"; | |||
-- 登录PHP成功之后开始检测未完成的订单 | |||
app:addEventListener("PHP_LGIN_SUCCESSED", handler(self, self.checkPurchase)); | |||
end | |||
-- 检测是否有未完成的订单 | |||
-- PHP登录完成后检测 | |||
function PluginIosPay:checkPurchase() | |||
if self.plugin then | |||
logD("PluginIosPay call checkPurchase") | |||
self.plugin:callVoid("checkPurchase"); | |||
end | |||
end | |||
-- 启动插件 | |||
function PluginIosPay:start() | |||
self:loadData() | |||
-- 必须主动申明支持苹果内购 | |||
if not PluginConfig or not PluginConfig.isSupportIAP then | |||
return | |||
end | |||
self.plugin = cc.PluginManager:getInstance():createPlugin("IAPApple" , "IAPApple"); | |||
if self.plugin then | |||
self.plugin:callVoid("setDebugMode" , true); | |||
local developerInfo = | |||
{ | |||
-- 回调函数 | |||
Listener = handler(self , self.onPayResult); | |||
}; | |||
self.plugin:callVoid("initIAP" , developerInfo); | |||
end | |||
end | |||
-- 停止插件 | |||
function PluginIosPay:stop() | |||
if self.plugin then | |||
cc.PluginManager:getInstance():removePlugin(self.plugin); | |||
self.plugin = nil; | |||
end | |||
end | |||
function PluginIosPay:isSupportPay() | |||
return true | |||
end | |||
-- 插件是否被支持 | |||
function PluginIosPay:isSupport() | |||
return self.plugin ~= nil; | |||
end | |||
function PluginIosPay:showWaitDialog(text) | |||
local waitUI = loadUI("res/ui/ui_tongyong/t_ios_paying.ui") | |||
waitUI.Items.ImageView_ring:playClip("rotate"); | |||
waitUI:setAnchorPoint(cc.p(0.5, 0.5)); | |||
waitUI.Items.Text_content:setText(text); | |||
self.waitDialog = app:showWaitUI(waitUI, nil, nil, false); | |||
end | |||
function PluginIosPay:closeWaitDialog() | |||
if not tolua.isnull(self.waitDialog) then | |||
self.waitDialog:removeFromParent() | |||
self.waitDialog = nil | |||
end | |||
end | |||
-- 支付 | |||
--[[ | |||
["10182"] = { | |||
["currency"] = 1, | |||
["desc"] = "", | |||
["ext"] = { | |||
}, | |||
["icon"] = http://img.dingdingqipai.com/images/goods/5cb7e2f9138ba.png?v=1555555065, | |||
["id"] = 10182, | |||
["name"] = 50房卡, | |||
["number"] = 50, | |||
["order"] = 100, | |||
["pay_type"] = { | |||
[1] = { | |||
["id"] = 1, | |||
["name"] = 苹果支付, | |||
}, | |||
}, | |||
["price"] = 10, | |||
["privilege_icon"] = , | |||
["product_id"] = com_dangdang_chuannan_10, | |||
["prop_id"] = 0, | |||
["type"] = 0, | |||
}, | |||
]] | |||
function PluginIosPay:pay(item) | |||
logD("PluginIosPay:pay() item = ", table.tostring(item)) | |||
if not item or not item.id then | |||
showTooltip("无效商品"); | |||
return | |||
end | |||
local url = getGlobalPhpUrl() | |||
local tt1 = | |||
{ | |||
action = "order.create", | |||
item_id = item.id, | |||
uid = app.user.loginInfo.uid, | |||
app = getAppId(), | |||
productid = item.product_id, | |||
pay_type = PayType.Apple, | |||
} | |||
logD("PluginIosPay:pay() tt1 = ", table.tostring(tt1)) | |||
logD("PluginIosPay:pay() url = ", url) | |||
app.waitDialogManager:showTransparencyMask() | |||
httpPost(url, tt1, function(status, response) | |||
app.waitDialogManager:closeTransparencyMask() | |||
logD("PluginIosPay:pay() status = ", tostring(status)) | |||
logD("PluginIosPay:pay() response = ", tostring(response)) | |||
if status ~= "successed" then | |||
return; | |||
end | |||
-- 状态码 | |||
local data = json.decode(response) | |||
if tonumber(data.code) ~= 200 then | |||
return | |||
end | |||
-- 订单号 | |||
if not data.result or not data.result.orderid then | |||
return | |||
end | |||
local tt2 = | |||
{ | |||
-- 商品ID | |||
productId = item.product_id; | |||
-- 商品数量 | |||
productNum = 1; | |||
-- 请求的信息 | |||
requestData = item.id .. "_" .. data.result.orderid; | |||
} | |||
--self:showWaitDialog("等待支付完成!"); | |||
app.waitDialogManager:showWaitNetworkDialog("等待支付完成!") | |||
self.plugin:callVoid("payForProduct" , tt2); | |||
end); | |||
end | |||
--[[ | |||
{"msg":\{"receiptData":"ewoJInNpZ25hdHVyZSIgPSAiQTU3T1loRkwveVByelRIU2t2eFBKWDJBVkhDa0tNZTlobjVkTUk0SXFFMHlDV2NaNGxyUmNONVltWmcxOVFZUnRnL2hSN2t3L2RFSW1DUEJ0RlU1VkFEWjZ3RkZzeWloWnYyUkg2bHQxN3k2UUFrdkVYNzNXN0pDZWk4a21obDNiOXBINUZ6TnM5dWxXQlZrSElibldBN3Vwd2FXb1VpeVBYbUNZSFkrRTFzK1NiYVVWdG9UMmh3WWtxb2M4Nk5YNGxxbG10Mm5qdkNxQkphaE1WV2laVVZ1NjYzZGl2RXVXUGZnOHZDWmZKZWE0UnlFM2ZRMUNyNGZGQ3hjMEtzNUMwWFQ4V1dPdHFiMFo3SnlRcUVwRDRlbG95eWFFUU9UVUFxM1FvU28rWVprTVAwYzQwWnBFZXNsUHF1Ni9qQWhIK3JwOWdJNGtqelNnU2lPZlljRzZpb0FBQVdBTUlJRmZEQ0NCR1NnQXdJQkFnSUlEdXRYaCtlZUNZMHdEUVlKS29aSWh2Y05BUUVGQlFBd2daWXhDekFKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFLREFwQmNIQnNaU0JKYm1NdU1Td3dLZ1lEVlFRTERDTkJjSEJzWlNCWGIzSnNaSGRwWkdVZ1JHVjJaV3h2Y0dWeUlGSmxiR0YwYVc5dWN6RkVNRUlHQTFVRUF3dzdRWEJ3YkdVZ1YyOXliR1IzYVdSbElFUmxkbVZzYjNCbGNpQlNaV3hoZEdsdmJuTWdRMlZ5ZEdsbWFXTmhkR2x2YmlCQmRYUm9iM0pwZEhrd0hoY05NVFV4TVRFek1ESXhOVEE1V2hjTk1qTXdNakEzTWpFME9EUTNXakNCaVRFM01EVUdBMVVFQXd3dVRXRmpJRUZ3Y0NCVGRHOXlaU0JoYm1RZ2FWUjFibVZ6SUZOMGIzSmxJRkpsWTJWcGNIUWdVMmxuYm1sdVp6RXNNQ29HQTFVRUN3d2pRWEJ3YkdVZ1YyOXliR1IzYVdSbElFUmxkbVZzYjNCbGNpQlNaV3hoZEdsdmJuTXhFekFSQmdOVkJBb01Da0Z3Y0d4bElFbHVZeTR4Q3pBSkJnTlZCQVlUQWxWVE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBcGMrQi9TV2lnVnZXaCswajJqTWNqdUlqd0tYRUpzczl4cC9zU2cxVmh2K2tBdGVYeWpsVWJYMS9zbFFZbmNRc1VuR09aSHVDem9tNlNkWUk1YlNJY2M4L1cwWXV4c1FkdUFPcFdLSUVQaUY0MWR1MzBJNFNqWU5NV3lwb041UEM4cjBleE5LaERFcFlVcXNTNCszZEg1Z1ZrRFV0d3N3U3lvMUlnZmRZZUZScjZJd3hOaDlLQmd4SFZQTTNrTGl5a29sOVg2U0ZTdUhBbk9DNnBMdUNsMlAwSzVQQi9UNXZ5c0gxUEttUFVockFKUXAyRHQ3K21mNy93bXYxVzE2c2MxRkpDRmFKekVPUXpJNkJBdENnbDdaY3NhRnBhWWVRRUdnbUpqbTRIUkJ6c0FwZHhYUFEzM1k3MkMzWmlCN2o3QWZQNG83UTAvb21WWUh2NGdOSkl3SURBUUFCbzRJQjF6Q0NBZE13UHdZSUt3WUJCUVVIQVFFRU16QXhNQzhHQ0NzR0FRVUZCekFCaGlOb2RIUndPaTh2YjJOemNDNWhjSEJzWlM1amIyMHZiMk56Y0RBekxYZDNaSEl3TkRBZEJnTlZIUTRFRmdRVWthU2MvTVIydDUrZ2l2Uk45WTgyWGUwckJJVXdEQVlEVlIwVEFRSC9CQUl3QURBZkJnTlZIU01FR0RBV2dCU0lKeGNKcWJZWVlJdnM2N3IyUjFuRlVsU2p0ekNDQVI0R0ExVWRJQVNDQVJVd2dnRVJNSUlCRFFZS0tvWklodmRqWkFVR0FUQ0IvakNCd3dZSUt3WUJCUVVIQWdJd2diWU1nYk5TWld4cFlXNWpaU0J2YmlCMGFHbHpJR05sY25ScFptbGpZWFJsSUdKNUlHRnVlU0J3WVhKMGVTQmhjM04xYldWeklHRmpZMlZ3ZEdGdVkyVWdiMllnZEdobElIUm9aVzRnWVhCd2JHbGpZV0pzWlNCemRHRnVaR0Z5WkNCMFpYSnRjeUJoYm1RZ1kyOXVaR2wwYVc5dWN5QnZaaUIxYzJVc0lHTmxjblJwWm1sallYUmxJSEJ2YkdsamVTQmhibVFnWTJWeWRHbG1hV05oZEdsdmJpQndjbUZqZEdsalpTQnpkR0YwWlcxbGJuUnpMakEyQmdnckJnRUZCUWNDQVJZcWFIUjBjRG92TDNkM2R5NWhjSEJzWlM1amIyMHZZMlZ5ZEdsbWFXTmhkR1ZoZFhSb2IzSnBkSGt2TUE0R0ExVWREd0VCL3dRRUF3SUhnREFRQmdvcWhraUc5Mk5rQmdzQkJBSUZBREFOQmdrcWhraUc5dzBCQVFVRkFBT0NBUUVBRGFZYjB5NDk0MXNyQjI1Q2xtelQ2SXhETUlKZjRGelJqYjY5RDcwYS9DV1MyNHlGdzRCWjMrUGkxeTRGRkt3TjI3YTQvdncxTG56THJSZHJqbjhmNUhlNXNXZVZ0Qk5lcGhtR2R2aGFJSlhuWTR3UGMvem83Y1lmcnBuNFpVaGNvT0FvT3NBUU55MjVvQVE1SDNPNXlBWDk4dDUvR2lvcWJpc0IvS0FnWE5ucmZTZW1NL2oxbU9DK1JOdXhUR2Y4YmdwUHllSUdxTktYODZlT2ExR2lXb1IxWmRFV0JHTGp3Vi8xQ0tuUGFObVNBTW5CakxQNGpRQmt1bGhnd0h5dmozWEthYmxiS3RZZGFHNllRdlZNcHpjWm04dzdISG9aUS9PamJiOUlZQVlNTnBJcjdONFl0UkhhTFNQUWp2eWdhWndYRzU2QWV6bEhSVEJoTDhjVHFBPT0iOwoJInB1cmNoYXNlLWluZm8iID0gImV3b0pJbTl5YVdkcGJtRnNMWEIxY21Ob1lYTmxMV1JoZEdVdGNITjBJaUE5SUNJeU1ERTNMVEEzTFRBMElESXhPakE0T2pRNElFRnRaWEpwWTJFdlRHOXpYMEZ1WjJWc1pYTWlPd29KSW5WdWFYRjFaUzFwWkdWdWRHbG1hV1Z5SWlBOUlDSTNZelZtWXpNMk16WXhZMkV5TURabVlXTXhOemxqWXpka1kyRXpaakl5TTJJNE9EWmtZV1prSWpzS0NTSnZjbWxuYVc1aGJDMTBjbUZ1YzJGamRHbHZiaTFwWkNJZ1BTQWlNVEF3TURBd01ETXhNalUxTlRjek1pSTdDZ2tpWW5aeWN5SWdQU0FpTVM0d0xqa2lPd29KSW5SeVlXNXpZV04wYVc5dUxXbGtJaUE5SUNJeE1EQXdNREF3TXpFeU5UVTFOek15SWpzS0NTSnhkV0Z1ZEdsMGVTSWdQU0FpTVNJN0Nna2liM0pwWjJsdVlXd3RjSFZ5WTJoaGMyVXRaR0YwWlMxdGN5SWdQU0FpTVRRNU9USXlOemN5T0RReU5TSTdDZ2tpZFc1cGNYVmxMWFpsYm1SdmNpMXBaR1Z1ZEdsbWFXVnlJaUE5SUNJelJEVkJNRGMwUlMwNE5UVXpMVFJHTVRZdE9FTXpPQzAwUWprek0wVTNNVUU1TlRVaU93b0pJbkJ5YjJSMVkzUXRhV1FpSUQwZ0ltTnZiUzVrYVc1blpHbHVaMmRoYldVdWNESXhMbU5oY21ReE1DSTdDZ2tpYVhSbGJTMXBaQ0lnUFNBaU1USTFOVFEzTlRJeU5TSTdDZ2tpWW1sa0lpQTlJQ0pqYjIwdVpHbHVaMlJwYm1kbllXMWxMbkF5TVNJN0Nna2ljSFZ5WTJoaGMyVXRaR0YwWlMxdGN5SWdQU0FpTVRRNU9USXlOemN5T0RReU5TSTdDZ2tpY0hWeVkyaGhjMlV0WkdGMFpTSWdQU0FpTWpBeE55MHdOeTB3TlNBd05Eb3dPRG8wT0NCRmRHTXZSMDFVSWpzS0NTSndkWEpqYUdGelpTMWtZWFJsTFhCemRDSWdQU0FpTWpBeE55MHdOeTB3TkNBeU1Ub3dPRG8wT0NCQmJXVnlhV05oTDB4dmMxOUJibWRsYkdWeklqc0tDU0p2Y21sbmFXNWhiQzF3ZFhKamFHRnpaUzFrWVhSbElpQTlJQ0l5TURFM0xUQTNMVEExSURBME9qQTRPalE0SUVWMFl5OUhUVlFpT3dwOSI7CgkiZW52aXJvbm1lbnQiID0gIlNhbmRib3giOwoJInBvZCIgPSAiMTAwIjsKCSJzaWduaW5nLXN0YXR1cyIgPSAiMCI7Cn0=","requestData":"MTAwOTA1MF8xNDk5MjI3Njk1","state":1,"productId":"com.dingdinggame.p21.card10","tradeSnid":"1000000312555732"\},"code":0\} | |||
--]] | |||
-- 把订单数据提交到服务器 | |||
function PluginIosPay:postReceiptData(msg) | |||
logD("PluginIosPay::postReceiptData() ") | |||
local msgData = json.decode(msg); | |||
logD("PluginIosPay::postReceiptData() msgData = ", table.tostring(msgData)); | |||
local msgData = json.decode(msg); | |||
local tradeSnid = msgData.tradeSnid; | |||
-- 将玩家的支付数据写本地 | |||
if tradeSnid ~= nil then | |||
self.payData[tradeSnid] = msgData; | |||
self:saveData() | |||
end | |||
local requestData = msgData.requestData; | |||
local arr = string.split(requestData, "_") | |||
local item_id = arr[1] | |||
local order_id = arr[2] | |||
local tt = | |||
{ | |||
action = "order.receipt", | |||
app = getAppId(), | |||
uid = app.user.loginInfo.uid, | |||
item_id = item_id, | |||
productid = msgData.productId, | |||
orderid = order_id, | |||
receipt = msgData.receiptData, | |||
} | |||
logD("PluginIosPay::postReceiptData() tt = ", table.tostring(tt)); | |||
local url = getGlobalPhpUrl() | |||
logD("PluginIosPay::postReceiptData() url = ", url) | |||
if not url or url == "" then | |||
return | |||
end | |||
httpPost(url, tt, function(status, response) | |||
logD("PluginIosPay::postReceiptData() status = ", tostring(status)); | |||
logD("PluginIosPay::postReceiptData() response = ", tostring(response)); | |||
if status ~= "successed" then | |||
return; | |||
end | |||
-- 状态码 | |||
local data = json.decode(response) | |||
if tonumber(data.code) ~= 200 then | |||
logD("PluginIosPay::postReceiptData() tradeSnid = ", tradeSnid); | |||
if tradeSnid then | |||
self.plugin:callVoid("finishPurchase" , tradeSnid); | |||
end | |||
return | |||
end | |||
-- 房卡数量 | |||
if not data.result or not data.result.card then | |||
return | |||
end | |||
-- 更新房卡数量 | |||
app.user.loginInfo.curCardNum = tonumber(data.result.card); | |||
showConfirmDialog("恭喜您充值成功,祝您游戏愉快!"); | |||
-- 通知 APPLE 订单完成 | |||
logD("PluginIosPay::postReceiptData() tradeSnid = ", tradeSnid); | |||
self.plugin:callVoid("finishPurchase" , tradeSnid); | |||
end ) | |||
end | |||
-- 回调函数 | |||
function PluginIosPay:onPayResult(result) | |||
local resultJson = json.decode(result); | |||
local ret = resultJson.code; | |||
local msg = resultJson.msg; | |||
logD("PluginIosPay:onPayResult() code = ", ret) | |||
if type(msg) == "table" then | |||
logD("PluginIosPay:onPayResult() msg = ", table.tostring(msg)) | |||
else | |||
logD("PluginIosPay:onPayResult() msg = ", tostring(msg)) | |||
end | |||
if ret == 0 then | |||
-- 打印信息 | |||
logD("AppleIAP:" , msg); | |||
elseif ret == 1 then | |||
-- 支付成功 | |||
app.waitDialogManager:closeWaitNetworkDialog() | |||
self:postReceiptData(msg); | |||
elseif ret == 2 then | |||
-- 发现有订单丢失的情况 | |||
-- 首先上报异常,上报成功之后删除订单 | |||
app.waitDialogManager:closeWaitNetworkDialog() | |||
self:postReceiptData(msg); | |||
elseif ret == 3 then | |||
-- 支付失败 | |||
app.waitDialogManager:closeWaitNetworkDialog() | |||
--showConfirmDialog(string.format("支付失败: %s", msg)); | |||
elseif ret == 4 then | |||
-- 支付取消 | |||
app.waitDialogManager:closeWaitNetworkDialog() | |||
--showConfirmDialog(string.format("支付取消: %s", msg)); | |||
else | |||
-- 未知的回调信息 | |||
app.waitDialogManager:closeWaitNetworkDialog() | |||
end | |||
end | |||
function PluginIosPay:loadData() | |||
logD("PluginIosPay:loadData()") | |||
local fileSting = loadStringFromFile(self.payDataFile) | |||
logD("PluginIosPay:loadData() fileSting = ", fileSting); | |||
if not fileSting or string.len(fileSting) <= 0 then | |||
return | |||
end | |||
local function loadFromFile() | |||
logD("PluginIosPay:loadData() loadFromFile") | |||
self.payData = json.decode(fileSting); | |||
end | |||
local function loadFromFileFailed() | |||
logE("PluginIosPay:loadData() loadFromFileFailed") | |||
end | |||
-- 容错处理 | |||
xpcall(loadFromFile, loadFromFileFailed); | |||
logD("PluginIosPay:loadData() self.payData = ", table.tostring(self.payData)) | |||
end | |||
function PluginIosPay:saveData() | |||
logD("PluginIosPay:saveData() payData = ", table.tostring(self.payData)) | |||
local fileSting = json.encode(self.payData) | |||
logD("PluginIosPay:saveData() fileSting = ", fileSting) | |||
saveStringToFile(fileSting, self.payDataFile); | |||
end | |||
return PluginIosPay; |
@@ -0,0 +1,224 @@ | |||
local PluginBase = require("luaScript.Plugins.PluginBase") | |||
local PluginWechat = class("PluginWechat" , PluginBase) | |||
local PluginConfig = require("preload.PluginConfig") | |||
function PluginWechat:ctor() | |||
PluginWechat.super.ctor(self); | |||
self.plugin = nil | |||
self.AcountId = nil | |||
self.SessionId = nil | |||
self.isInstalled = false | |||
self.pluginKey = "PluginWechat"; | |||
end | |||
-- 启动插件 | |||
function PluginWechat:start() | |||
if isAndroidPlatform() then | |||
self.plugin = cc.PluginManager:getInstance():createPlugin("PluginWechat" , "com/ddgame/plugin/PluginWechat"); | |||
elseif isIOSPlatform() then | |||
self.plugin = cc.PluginManager:getInstance():createPlugin("PluginWechat" , "PluginWechat"); | |||
end | |||
if self.plugin then | |||
local developerInfo = | |||
{ | |||
appId = PluginConfig.WeiXin.appId, | |||
appKey = PluginConfig.WeiXin.appKey, | |||
appSign = PluginConfig.WeiXin.appSign, | |||
appName = PluginConfig.WeiXin.appName, | |||
partnerId = PluginConfig.WeiXin.partnerId, | |||
universalLink = PluginConfig.WeiXin.universalLink, | |||
permissions = "snsapi_login", | |||
pluginKey = self.pluginKey, | |||
callback = handler(self, self.onResult), -- 回调函数 | |||
}; | |||
logD("PluginWechat:start(), developerInfo = ", table.tostring(developerInfo)) | |||
self.plugin:callVoid("initPlugin", developerInfo) | |||
end | |||
end | |||
-- 停止插件 | |||
function PluginWechat:stop() | |||
if self.plugin then | |||
cc.PluginManager:getInstance():removePlugin(self.plugin); | |||
self.plugin = nil; | |||
end | |||
end | |||
function PluginWechat:isSupport() | |||
return self.isInstalled == true; | |||
end | |||
function PluginWechat:isSupportPay() | |||
return false | |||
end | |||
-- 请求登录 | |||
function PluginWechat:login(tt) | |||
log("PluginWechat:login", table.tostring(tt)) | |||
if not self.isInstalled then | |||
showTooltip("未安装微信或者微信版本过低,请安装最新版本的微信后再试") | |||
return; | |||
end | |||
self:start(); | |||
if self.plugin then | |||
self.plugin:callVoid("login",tt or {}) | |||
end | |||
end | |||
-- 请求登出 | |||
function PluginWechat:logout(tt) | |||
log("PluginWechat:logout", table.tostring(tt)) | |||
-- IOS没做登出 | |||
end | |||
function PluginWechat:pay(tt) | |||
log("PluginWechat:pay", table.tostring(tt)) | |||
if not self.isInstalled then | |||
showTooltip("未安装微信或者微信版本过低,请安装最新版本的微信后再试") | |||
return; | |||
end | |||
self:start(); | |||
if self.plugin then | |||
self.plugin:callVoid("pay",tt or {}) | |||
end | |||
end | |||
-- 跳转至微信 | |||
function PluginWechat:gotoWeiXin() | |||
log("PluginWechat:gotoWeiXin() ") | |||
if not self.isInstalled then | |||
showTooltip("未安装微信或者微信版本过低,请安装最新版本的微信后再试") | |||
return; | |||
end | |||
self:start(); | |||
if self.plugin then | |||
self.plugin:callVoid("gotoWeiXin"); | |||
end | |||
end | |||
-- 分享链接给好友 | |||
function PluginWechat:shareGame(tt, shareCallbakc) | |||
log("PluginWechat:shareGame(), ", table.tostring(tt)) | |||
if not self.isInstalled then | |||
showTooltip("未安装微信或者微信版本过低,请安装最新版本的微信后再试") | |||
return; | |||
end | |||
self:start(); | |||
if self.plugin then | |||
self.shareCallbakc = shareCallbakc | |||
self.plugin:callVoid("shareGame", tt or {}); | |||
end | |||
end | |||
-- 回调函数 | |||
function PluginWechat:onResult(result) | |||
log("PluginWechat:onResult() result = ", result) | |||
local resultJson = json.decode(result); | |||
if not resultJson then | |||
return | |||
end | |||
local pluginKey = tostring(resultJson.pluginKey) | |||
if pluginKey ~= self.pluginKey then | |||
return | |||
end | |||
local code = tonumber(resultJson.code); | |||
local msg = json.decode(resultJson.message); | |||
if code == self.Code.INIT_SUCCESS then | |||
self.isInstalled = true | |||
elseif code == self.Code.INIT_FAIL then | |||
self.isInstalled = false | |||
elseif code == self.Code.LOGIN_SUCCESS then | |||
--是否绑定微信true代表绑定,false代表登录 | |||
if app.user.bindWeiXinIng or app.user.bindWeiXinTwice then | |||
local openid = msg.openid | |||
local unionid = msg.unionid | |||
local sex = msg.sex or 0 | |||
local nickname = msg.nickname or "" | |||
local headimgurl = msg.headimgurl or "" | |||
local access_token = msg.access_token or "" | |||
local refresh_token = msg.refresh_token or "" | |||
--app.user:updateUserInfo() | |||
app.user.bindWeiXinIng = false | |||
local tt = { | |||
openid = msg.openid, | |||
unionid = msg.unionid, | |||
nickname = msg.nickname or "", | |||
sex = tonumber(msg.sex) or 0, | |||
headimgurl = msg.headimgurl or "", | |||
areano = app.user.areano, | |||
gpsInfo = app.user.gpsInfo, | |||
access_token = msg.access_token or "", | |||
refresh_token = msg.refresh_token or "", | |||
phonenum = app.user.phonenum, | |||
password = app.user.password, | |||
deviceInfo = app.user.strUserDeviceInfo, | |||
} | |||
local weixinInfo = json.encode(tt); | |||
--绑定微信请求 | |||
local request = PhoneBindRequest:new() | |||
request.uid = app.user.loginInfo.uid | |||
request.checkcode = "" | |||
request.weixinInfo = weixinInfo | |||
request.rewardType = 5 -- 奖励类型:1. 房卡 2.金币 3. 活动房卡 4. RMB 5. 红包券 | |||
if app.user.bindWeiXinTwice then | |||
logD("yhj: 微信二次授权") | |||
request.bindType = BIND_TYPE.WEIXIN_TWICE_BIND | |||
request.account = msg.openid | |||
request.password = msg.unionid | |||
app.user.bindWeiXinTwice = false | |||
else | |||
logD("yhj: 普通微信绑定") | |||
request.bindType = BIND_TYPE.WEIXIN | |||
request.account = app.user.phonenum | |||
request.password = "" | |||
end | |||
-- | |||
app.user:dispatchEvent({name = "onWetChatBindRequest",request = request}); | |||
else | |||
app.user.openid = msg.openid | |||
app.user.unionid = msg.unionid | |||
app.user.sex = msg.sex or 0 | |||
app.user.nickname = msg.nickname or "" | |||
app.user.headimgurl = msg.headimgurl or "" | |||
app.user.access_token = msg.access_token or "" | |||
app.user.refresh_token = msg.refresh_token or "" | |||
logD("yhj: 正常微信登录") | |||
app.user.loginType = 0 | |||
--app:dispatchEvent({name = "thirdLoginResutl" }); | |||
loginToken(); | |||
showTooltip("微信授权成功,正在登陆服务器,请稍后!") | |||
end | |||
elseif code == self.Code.LOGIN_FAIL then | |||
--showTooltip("微信登录失敗") | |||
--app:dispatchEvent({name = "thirdLoginResutl" }); | |||
elseif code == self.Code.SHARE_SUCCESS then | |||
showTooltip("微信分享成功") | |||
if self.shareCallbakc and type(self.shareCallbakc) == "function" then | |||
self.shareCallbakc() | |||
end | |||
elseif code == self.Code.SHARE_CANCEL then | |||
showTooltip("微信分享取消") | |||
elseif code == self.Code.SHARE_FAIL then | |||
showTooltip("微信分享失败") | |||
end | |||
end | |||
return PluginWechat |
@@ -0,0 +1,127 @@ | |||
local PluginBase = require("luaScript.Plugins.PluginBase") | |||
local PluginWechatShare = class("PluginWechatShare" , PluginBase) | |||
function PluginWechatShare:ctor() | |||
PluginWechatShare.super.ctor(self); | |||
self.appId = ""; | |||
self.appKey = ""; | |||
self.plugin = nil | |||
self.AcountId = nil | |||
self.SessionId = nil | |||
self.isInstalled = false | |||
self.pluginKey = "PluginWechatShare"; | |||
end | |||
-- 启动插件 | |||
function PluginWechatShare:start(appid, secret) | |||
logD("PluginWechatShare::start()", appid, secret); | |||
self.appId = appid or self.appId; | |||
self.appKey = secret or self.appKey; | |||
if isAndroidPlatform() then | |||
self.plugin = cc.PluginManager:getInstance():createPlugin("PluginWechatShare" , "com/ddgame/plugin/PluginWechat"); | |||
elseif isIOSPlatform() then | |||
self.plugin = cc.PluginManager:getInstance():createPlugin("PluginWechatShare" , "PluginWechat"); | |||
end | |||
if self.plugin then | |||
local developerInfo = | |||
{ | |||
appId = self.appId, | |||
appKey = self.appKey, | |||
appSign = "", | |||
appName = "", | |||
partnerId = "", | |||
universalLink = "", | |||
permissions = "snsapi_userinfo", | |||
pluginKey = self.pluginKey, | |||
callback = handler(self, self.onResult), -- 回调函数 | |||
}; | |||
logD("PluginWechatShare::start(), developerInfo = ", table.tostring(developerInfo)); | |||
self.plugin:callVoid("initPlugin", developerInfo) | |||
end | |||
end | |||
-- 停止插件 | |||
function PluginWechatShare:stop() | |||
if self.plugin then | |||
cc.PluginManager:getInstance():removePlugin(self.plugin); | |||
self.plugin = nil; | |||
end | |||
end | |||
-- 分享链接给好友 | |||
function PluginWechatShare:shareGame(tt, shareCallbakc) | |||
logD("PluginWechatShare:shareGame(), ", table.tostring(tt)) | |||
if not self.isInstalled then | |||
showTooltip("未安装微信或者微信版本过低,请安装最新版本的微信后再试") | |||
return; | |||
end | |||
-- 重新初始化 | |||
self:start(); | |||
if self.plugin then | |||
self.shareCallbakc = shareCallbakc | |||
self.plugin:callVoid("shareGame", tt or {}); | |||
end | |||
end | |||
-- 回调函数 | |||
function PluginWechatShare:onResult(result) | |||
logD("PluginWechatShare:onResult() result = ", result) | |||
local resultJson = json.decode(result); | |||
if not resultJson then | |||
return | |||
end | |||
local pluginKey = tostring(resultJson.pluginKey) | |||
if pluginKey ~= self.pluginKey then | |||
return | |||
end | |||
local code = tonumber(resultJson.code); | |||
local msg = json.decode(resultJson.message); | |||
if code == self.Code.INIT_SUCCESS then | |||
self.isInstalled = true | |||
elseif code == self.Code.INIT_FAIL then | |||
self.isInstalled = false | |||
elseif code == self.Code.LOGIN_SUCCESS then | |||
--[[app.user.openid = msg.openid | |||
app.user.unionid = msg.unionid | |||
app.user.sex = msg.sex or 0 | |||
app.user.nickname = msg.nickname or "" | |||
app.user.headimgurl = msg.headimgurl or "" | |||
app.user.access_token = msg.access_token or "" | |||
app.user.refresh_token = msg.refresh_token or "" | |||
app.user.loginType = 0 | |||
app:dispatchEvent({name = "thirdLoginResutl" }); | |||
loginToken(); | |||
showTooltip("微信授权成功,正在登陆服务器,请稍后!")--]] | |||
elseif code == self.Code.LOGIN_FAIL then | |||
--showTooltip("微信登录失敗") | |||
app:dispatchEvent({name = "thirdLoginResutl" }); | |||
elseif code == self.Code.SHARE_SUCCESS then | |||
showTooltip("微信分享成功") | |||
if self.shareCallbakc and type(self.shareCallbakc) == "function" then | |||
self.shareCallbakc() | |||
end | |||
elseif code == self.Code.SHARE_CANCEL then | |||
showTooltip("微信分享取消") | |||
elseif code == self.Code.SHARE_FAIL then | |||
showTooltip("微信分享失败") | |||
end | |||
end | |||
return PluginWechatShare |
@@ -0,0 +1,153 @@ | |||
local PluginBase = require("luaScript.Plugins.PluginBase") | |||
local PluginYaya = class("PluginYaya" , PluginBase) | |||
function PluginYaya:ctor() | |||
PluginYaya.super.ctor(self); | |||
self.plugin = nil | |||
self.pluginKey = "PluginYaya"; | |||
end | |||
-- 启动插件 | |||
function PluginYaya:start() | |||
log("PluginYaya::start()") | |||
if isAndroidPlatform() then | |||
self.plugin = cc.PluginManager:getInstance():createPlugin("PluginYaya" , "com/ddgame/plugin/PluginYaya"); | |||
elseif isIOSPlatform() then | |||
self.plugin = cc.PluginManager:getInstance():createPlugin("PluginYaya" , "PluginYaya"); | |||
end | |||
if self.plugin then | |||
local userInfo = json.decode(app.user.userInfo) | |||
local tName = string.getShortName2(userInfo.nickname, 4) or tostring(app.user.loginInfo.uid) | |||
local developerInfo = | |||
{ | |||
appId = "1002779", | |||
userId = app.user.loginInfo.uid, | |||
userName = tName, | |||
serverId = "3",--getGameId(), | |||
maxRecordTime = 30, | |||
pluginKey = self.pluginKey, | |||
callback = handler(self, self.onResult); -- 回调函数 | |||
}; | |||
log("PluginYaya::start() developerInfo = ", table.tostring(developerInfo)) | |||
self.plugin:callVoid("initPlugin", developerInfo); | |||
else | |||
log("PluginYaya::start() failed") | |||
end | |||
end | |||
-- 停止插件 | |||
function PluginYaya:stop() | |||
if self.plugin then | |||
cc.PluginManager:getInstance():removePlugin(self.plugin); | |||
self.plugin = nil; | |||
end | |||
end | |||
-- 开始录音 | |||
function PluginYaya:startRecord() | |||
if self.plugin then | |||
self.plugin:callVoid("startRecord"); | |||
end | |||
end | |||
-- 取消录音 | |||
function PluginYaya:cancelRecord() | |||
if self.plugin then | |||
self.plugin:callVoid("cancelRecord"); | |||
end | |||
end | |||
-- 结束录音 | |||
function PluginYaya:stopRecord() | |||
if self.plugin then | |||
self.plugin:callVoid("stopRecord"); | |||
end | |||
end | |||
-- 播放录音 | |||
function PluginYaya:playRecord(filePath) | |||
log("PluginYaya:playRecord() filePath = ", filePath); | |||
-- 记录回调 | |||
if self.plugin then | |||
local data = | |||
{ | |||
filePath = tostring(filePath) | |||
} | |||
log("PluginYaya:playRecord() data = ", table.tostring(data)) | |||
self.plugin:callVoid("playRecord", data); | |||
end | |||
end | |||
-- 停止播放录音 | |||
function PluginYaya:stopPlayRecord() | |||
log("PluginYaya:stopPlayRecord() "); | |||
if self.plugin then | |||
self.plugin:callVoid("stopPlayRecord"); | |||
end | |||
end | |||
-- 下载录音 | |||
function PluginYaya:downloadRecord(nUserId, recordUrl, downloadCallback) | |||
self.downloadCallback = downloadCallback | |||
if self.plugin then | |||
local data = | |||
{ | |||
recordTag = tostring(nUserId), | |||
recordUrl = tostring(recordUrl), | |||
play = true, | |||
} | |||
log("PluginYaya:downloadRecord() data = ", table.tostring(data)) | |||
self.plugin:callVoid("downloadRecord", data); | |||
end | |||
end | |||
-- 回调函数 | |||
function PluginYaya:onResult(result) | |||
log("PluginYaya:onResult() result = ", result) | |||
local resultJson = json.decode(result); | |||
if not resultJson then | |||
return | |||
end | |||
local pluginKey = tostring(resultJson.pluginKey) | |||
if pluginKey ~= self.pluginKey then | |||
return | |||
end | |||
local code = tonumber(resultJson.code); | |||
local info = json.decode(resultJson.message); | |||
if code == self.Code.INIT_SUCCESS then -- 初始化成功 | |||
--showTooltip("呀呀语音 初始化成功") | |||
print("初始化成功", "info = ", table.tostring(info)) | |||
elseif code == self.Code.INIT_FAIL then -- 初始化失败 | |||
--showTooltip("呀呀语音 初始化失败") | |||
print("初始化失败", "info = ", table.tostring(info)) | |||
elseif code == self.Code.RECORD_SUCCESS then -- 录音成功 | |||
--showTooltip("呀呀语音 录音成功") | |||
print("录音成功", "info = ", table.tostring(info)) | |||
app:dispatchEvent({name = "recordCallback", filePath = info.filePath, recordUrl = info.recordUrl, recordTime = info.recordTime }); | |||
elseif code == self.Code.RECORD_FAIL then -- 录音失败 | |||
--showTooltip("呀呀语音 录音失败") | |||
print("录音失败", "info = ", table.tostring(info)) | |||
elseif code == self.Code.RECORD_DOWNLOAD_SUCCESS then -- 录音下载成功 | |||
--showTooltip("呀呀语音 录音下载成功") | |||
print("录音下载成功", "info = ", table.tostring(info)) | |||
if self.downloadCallback then | |||
self.downloadCallback(info.recordTag, info.filePath); | |||
end | |||
elseif code == self.Code.RECORD_DOWNLOAD_FAIL then -- 录音下载失败 | |||
--showTooltip("呀呀语音 录音下载失败") | |||
print("录音下载失败", "info = ", table.tostring(info)) | |||
end | |||
end | |||
return PluginYaya |
@@ -0,0 +1,13 @@ | |||
local PluginBase = require("luaScript.Plugins.PluginBase") | |||
local PluginZhuCheng = class("PluginZhuCheng", PluginBase) | |||
function PluginZhuCheng:ctor() | |||
PluginZhuCheng.super.ctor(self); | |||
end | |||
function PluginZhuCheng:gotoWeiXin() | |||
showTooltip("当前平台不支持该操作!") | |||
end | |||
return PluginZhuCheng |
@@ -0,0 +1,333 @@ | |||
require("luaScript.cc.functions") | |||
BindableArray = class("BindableArray") | |||
function BindableArray:pairs() | |||
return pairs(self.Datas) | |||
end | |||
function BindableArray:ipairs() | |||
return ipairs(self.Datas) | |||
end | |||
function BindableArray:__pairs() | |||
return pairs(self.Datas) | |||
end | |||
function BindableArray:__ipairs() | |||
return ipairs(self.Datas) | |||
end | |||
function BindableArray:len() | |||
return self:size(); | |||
end | |||
function BindableArray:__len() | |||
return self:size(); | |||
end | |||
-- 删除数据 | |||
function BindableArray:clear() | |||
local datas = self.Datas; | |||
self.Datas = {} | |||
self.DataCount = 0 | |||
for i , v in pairs(datas) do | |||
self:raiseEvent("__remove" , i , v); | |||
end | |||
end | |||
-- 排序Datas数据表,当然了,老规矩,排序的表只支持:insert进来的数据,即键是正整数 | |||
function BindableArray:sort(func) | |||
table.sort(self.Datas , func); | |||
end | |||
-- 获得元素数量 | |||
function BindableArray:size() | |||
return self.DataCount | |||
end | |||
-- 添加元素数量 | |||
function BindableArray:insert(value) | |||
self[self:size() + 1] = value; | |||
end | |||
-- 绑定变量属性修改 | |||
function BindableArray:bind(name , onChangeFunc) | |||
if self[name] == nil then | |||
error("找不到成员变量:" .. name) | |||
return; | |||
end | |||
local bindIndex = self:bindEvent(name , onChangeFunc); | |||
onChangeFunc(name , self[name]); | |||
return bindIndex; | |||
end | |||
-- 绑定一个事件 | |||
function BindableArray:bindEvent(eventName , onAddFunc) | |||
if type(onAddFunc) ~= "function" then | |||
error("is not a function") | |||
return | |||
end | |||
local name = eventName | |||
if self.Binds[name] == nil then | |||
self.Binds[name] = {} | |||
self.Binds[name]._looping = 0 | |||
self.Binds[name].funs = {} | |||
end | |||
local index = self.BindIndex; | |||
-- 如果正在遍历过程中 | |||
local bindTable = self.Binds[name] | |||
if bindTable._looping > 0 then | |||
if self.AddBinds[name] == nil then | |||
self.AddBinds[name] = {} | |||
end | |||
-- 添加到临时列表 | |||
self.AddBinds[name][index] = onAddFunc | |||
else | |||
-- 不在遍历过程中立马加入 | |||
bindTable.funs[index] = onAddFunc; | |||
end | |||
self.BindsByIndex[index] = name; | |||
self.BindIndex = self.BindIndex + 1 | |||
return index; | |||
end | |||
-- 解除数据绑定 | |||
function BindableArray:unbind(bindIndex) | |||
local name = self.BindsByIndex[bindIndex] | |||
if name then | |||
-- 如果正在遍历过程中 | |||
local bindTable = self.Binds[name]; | |||
if bindTable._looping > 0 then | |||
if self.RemoveBinds[name] == nil then | |||
self.RemoveBinds[name] = {} | |||
end | |||
-- 添加到临时列表 | |||
self.RemoveBinds[name][bindIndex] = true | |||
else | |||
-- 不在遍历过程中立马移除 | |||
bindTable.funs[bindIndex] = nil; | |||
end | |||
self.BindsByIndex[bindIndex] = nil; | |||
end | |||
end | |||
function BindableArray:raiseEvent(eventName , key , value) | |||
local bindTable = self.Binds[eventName] | |||
if bindTable == nil then | |||
return | |||
end | |||
local funcs = bindTable.funs; | |||
if funcs then | |||
bindTable._looping = bindTable._looping + 1 | |||
-- 这里需要判断回调是否失效 | |||
local bindsIndex = self.BindsByIndex | |||
for i, v in pairs(funcs) do | |||
if bindsIndex[i] then | |||
v(key , value); | |||
end | |||
end | |||
bindTable._looping = bindTable._looping - 1 | |||
-- 如果在遍历过程中则等执行完 | |||
if bindTable._looping > 0 then | |||
print("raiseEvent在遍历的过程中,又触发了一次,当前遍历的次数", eventName, bindTable._looping) | |||
return | |||
end | |||
-- 处理新移除 | |||
local addBindFunc = self.AddBinds[eventName] | |||
local removeBindFunc = self.RemoveBinds[eventName] | |||
if removeBindFunc then | |||
print("BindableArray:raiseEvent过程中需要删除的绑定事件", table.toString(self.RemoveBinds)) | |||
for i, v in pairs(removeBindFunc) do | |||
-- 新增列表里面有则也要清掉 | |||
if addBindFunc then | |||
addBindFunc[i] = nil | |||
end | |||
funcs[i] = nil | |||
end | |||
-- 清空临时列表 | |||
self.RemoveBinds[eventName] = nil | |||
end | |||
-- 处理新增加 | |||
if addBindFunc then | |||
print("BindableArray:raiseEvent过程中需要增加的绑定事件", table.toString(self.AddBinds)) | |||
for i, v in pairs(addBindFunc) do | |||
funcs[i] = v | |||
end | |||
-- 清空临时列表 | |||
self.AddBinds[eventName] = nil | |||
end | |||
end | |||
end | |||
-- 绑定添加元素事件 | |||
function BindableArray:bindAdd(onAddFunc) | |||
return self:bindEvent("__add" , onAddFunc); | |||
end | |||
-- 绑定移除元素事件 | |||
function BindableArray:bindRemove(onRemoveFunc) | |||
return self:bindEvent("__remove" , onRemoveFunc); | |||
end | |||
-- 绑定更新事件 (update) | |||
function BindableArray:bindUpdateTo(onUpdateFunc) | |||
return self:bindEvent("__updateTo" , onUpdateFunc); | |||
end | |||
-- 绑定每一个元素的更新事件 | |||
function BindableArray:bindUpdate(onUpdateFunc) | |||
return self:bindEvent("__update" , onUpdateFunc); | |||
end | |||
-- 绑定设置元素事件 | |||
function BindableArray:bindSet(onSetFunc) | |||
return self:bindEvent("__set" , onSetFunc); | |||
end | |||
-- 把类数据写入到流 | |||
function BindableArray:write(stream) | |||
NetStream.writeNetVar(rawget(self , "NetVar") , stream , self); | |||
end | |||
-- 把类数据发送到服务器 | |||
function BindableArray:send(moduleID , commandID, net) | |||
if not net then | |||
log(debug.traceback()) | |||
assert(false); | |||
return | |||
end | |||
local stream = NetStream.new(); | |||
self:write(stream); | |||
net:send(moduleID , commandID , stream); | |||
NetStream.delete(stream); | |||
end | |||
-- 获取属性回调 | |||
function BindableArray:__index(key) | |||
local value = self.Datas[key]; | |||
if value ~= nil then | |||
return value; | |||
else | |||
local value = BindableArray[key]; | |||
if value then | |||
return value; | |||
else | |||
return nil; | |||
end | |||
end | |||
end | |||
-- 设置属性回调 | |||
function BindableArray:__newindex(key , value) | |||
local eventName; | |||
local datas = self.Datas; | |||
local oldValue = datas[key]; | |||
-- 新增 | |||
if oldValue == nil and value ~= nil then | |||
datas[key] = value | |||
self.DataCount = self.DataCount + 1 | |||
eventName = "__add" | |||
-- 删除 | |||
elseif oldValue ~= nil and value == nil then | |||
datas[key] = value | |||
self.DataCount = self.DataCount - 1 | |||
eventName = "__remove" | |||
-- 没修改 | |||
elseif oldValue == value then | |||
return; | |||
-- 修改 | |||
else | |||
datas[key] = value | |||
self:raiseEvent(key , key , value); | |||
eventName = "__set" | |||
end | |||
self:raiseEvent(eventName , key , value); | |||
-- 总是发生一个__update | |||
self:raiseEvent("__update" , key , value); | |||
end | |||
-- 用以处理数据绑定的更新数据 | |||
function BindableArray:updateTo(target) | |||
if target == nil or type(target) ~= "table" then | |||
return self; | |||
end | |||
-- 处理新增和修改 | |||
for i , v in self:pairs() do | |||
local updated = false; | |||
if type(v) == "table" then | |||
if type(v.updateTo) == "function" then | |||
if target[i] ~= nil then | |||
target[i] = v:updateTo(target[i]) | |||
updated = true; | |||
end | |||
end | |||
end | |||
if not updated then | |||
target[i] = v; | |||
end | |||
end | |||
-- 处理删除 | |||
for i , v in target:pairs() do | |||
if self[i] == nil then | |||
target[i] = nil; | |||
end | |||
end | |||
target:raiseEvent("__updateTo" , target); | |||
return target; | |||
end | |||
function BindableArray:cloneTo(target) | |||
for i , v in self:pairs() do | |||
local cloned = false; | |||
if type(v) == "table" then | |||
if type(v.clone) == "function" then | |||
target[i] = v:clone(); | |||
cloned = true; | |||
end | |||
end | |||
if not cloned then | |||
target[i] = v; | |||
end | |||
end | |||
end | |||
-- 深度克隆对象 | |||
function BindableArray:clone() | |||
local newArray = newBindableArray(); | |||
self:cloneTo(newArray); | |||
return newArray; | |||
end | |||
-- 创建一个带数据绑定功能的对象 | |||
function _newBindableArray(sourceTable) | |||
if type(sourceTable) ~= "table" then | |||
print(table.tostring(sourceTable)) | |||
end | |||
local obj = {} | |||
obj.Binds = {} | |||
obj.AddBinds = {} | |||
obj.RemoveBinds = {} | |||
obj.BindsByIndex = {} | |||
obj.BindIndex = 0; | |||
if sourceTable then | |||
obj.Datas = sourceTable | |||
local size = 0; | |||
for i , v in pairs(sourceTable) do | |||
size = size + 1; | |||
end | |||
obj.DataCount = size; | |||
else | |||
obj.Datas = {} | |||
obj.DataCount = 0; | |||
end | |||
obj.NetVar = nil; | |||
return obj | |||
end | |||
-- 创建一个带数据绑定功能的对象 | |||
local function newBindableArray(sourceTable) | |||
local obj = _newBindableArray(sourceTable) | |||
setmetatable(obj , BindableArray) | |||
return obj | |||
end | |||
return newBindableArray; |
@@ -0,0 +1,182 @@ | |||
local ClubCmd = { | |||
PHP_CLUB_LIST = "group.lists", --获取茶馆列表 | |||
PHP_CLUB_CREATE = "group.createGroup", --创建茶馆 | |||
PHP_CLUB_JOIN = "group.apply", --加入茶馆 | |||
PHP_CLUB_GET_GAME_RULE = "group.getGameruleConfig", --获取游戏玩法 | |||
PHP_CLUB_CHANGE_RULE = "group.gameset", --修改游戏玩法 | |||
PHP_CLUB_TABLE = "group.home", --茶馆桌子 | |||
PHP_CLUB_TABLE_LIST = "group.roomList", --茶馆桌子(新接口,支持分页) | |||
PHP_CLUB_SET = "group.setup", --茶馆设置(1 => 状态操作茶馆(管理员) $value 1正常2冻结0解散, 2 => 加入设置 (管理员) $value 1需要申请,0无需申请, 3 => 修改昵称(管理员) $value 新群名) | |||
PHP_CLUB_EXIT = "group.exitGroup", --退出茶馆 | |||
PHP_CLUB_PLAYER_LIST = "group.member", --成员列表 | |||
PHP_CLUB_REMOVE_PLAYER = "group.kickmember", --踢出成员 | |||
PHP_CLUB_MANAGER_MSG = "group.groupmsg", --茶馆消息(只限管理员) | |||
PHP_CLUB_APPLY_MSG = "group.applylist", --玩家申请加入茶馆消息 | |||
PHP_CLUB_EXIT_APPLY_MSG = "group.exitapplylist", --玩家申请退出亲友圈消息 | |||
PHP_CLUB_CHANGE_APPLY_STATUS = "group.applystatus", --处理申请消息 | |||
PHP_CLUB_CHANGE_EXIT_APPLY_STATUS = "group.exitapplystatus", -- 处理退出申请消息 | |||
PHP_CLUB_ADD_PLAYER = "group.addMember", --增加成员 | |||
PHP_CLUB_IMPORT_PLAYER = "group.importMember", --导入成员 | |||
PHP_CLUB_ONE_CLUB = "group.groupInfo", --单个茶馆信息 | |||
PHP_CLUB_PLAYER_SET = "group.memberStatus", --茶馆成员设置 | |||
PHP_CLUB_BIND_WECHAT_GROUP = "group.agentGroup", --已绑定的微信群 | |||
PHP_CLUB_WECHAT_GROUP = "group.getAgentGroupList", --获取微信群数据 | |||
PHP_CLUB_BIND_WECHAT = "group.setbindAgentGroup", --绑定微信/取消绑定 | |||
PHP_CLUB_BIND_WECHAT_PLAYER = "group.getAgentGroupMembers", --可绑定微信群的群成员 | |||
PHP_CLUB_AWARD_LIST = "group.getAwardList", --获取奖励内容列表 | |||
PHP_CLUB_GET_REWARD = "group.receiveAward", --领取奖励 | |||
PHP_CLUB_TRANSFER = "group.transferOwner", --茶馆转让 | |||
PHP_CLUB_UPDATE_NOTICE = "group.notice", --更新茶馆公告 | |||
PHP_CLUB_RULE_LIST = "group.gamerules", --茶馆包间列表 | |||
PHP_CLUB_RULE_SET = "group.privateRoomSetup", --切换包间 | |||
PHP_CLUB_TASK_LIST = "group.customTasksList", --茶馆自定义活动列表 | |||
PHP_CLUB_INSERT_TASK = "group.insertCustomTasks", --茶馆新增自定义活动 | |||
PHP_CLUB_SETUP_TASK = "group.customTasksSetup", --茶馆自定义活动修改 | |||
PHP_CLUB_OFFICIAL_ACTIVITY = "group.tasks", --茶馆官方活动 | |||
PHP_CLUB_SEND_BROADCAST = "group.broadcast", --茶馆主动发送广播 | |||
PHP_CLUB_MEMBER_SET = "group.memberSetup", --用户个性化配置 | |||
PHP_CLUB_MEMBER_STAT = "group.memberStat", --查询用户大赢家次数和总局数 | |||
PHP_CLUB_GET_JZ_SAME_TABLE = "group.getNotDeskmate", --获取玩家禁止同桌列表 | |||
PHP_CLUB_SET_JZ_SAME_TABLE = "group.setNotDeskmate", --设置禁止同桌 | |||
PHP_CLUB_GET_FORBID_SAME_TABLE_LIST = "group.getNotDeskmates", --获取当前已设置的禁止同桌玩家列表 | |||
PHP_CLUB_GET_ZHANJI_GROUP_DATE_LIST = "group.getGroupDateStatList", --茶馆战绩每日统计 | |||
PHP_CLUB_CHANGE_TOTAL_SCORE = "group.setTotalScore", --修改成员输赢积分(即疲劳值) | |||
PHP_CLUB_SET_HINTS = "group.setHints", --设置红点 | |||
PHP_CLUB_GET_COPARTNER_SUB = "group.getCopartnerSub", --获取所有合伙人对应的下线 | |||
PHP_CLUB_COPARTNER_SET_UP = "group.copartnerSetup", --给合伙人设置下线 | |||
PHP_CLUB_GET_COPARTNER_STAT = "group.getCopartnerStat", --合伙人(所有合伙人&统计) | |||
PHP_CLUB_GET_COPARTNER_DETAIL = "group.getCopartnerDetail", --合伙人贡献详情 | |||
PHP_CLUB_SET_MORE = "group.setups", --多设置消息 | |||
PHP_CLUB_SET_RED_FLOWER = "group.setMArenaScore", --调配红花(可批量) | |||
PHP_CLUB_RED_FLOWER_RECORD = "group.getArenaLog", --红花记录 | |||
PHP_CLUB_CANCELCOPARNER = "group.cancelCopartnerStatus", --取消合伙人通知操作 | |||
PHP_CLUB_ARENACOPARTNERSETUP = "group.arenaCopartnerSetup", --给比赛场合伙人设置下线 | |||
PHP_CLUB_MEMBER_INFO = "group.memberInfo", --获取单个成员信息 | |||
PHP_CLUB_IMPORT_MEMBER = "group.importBefore", --导入亲友圈成员新接口 | |||
PHP_CLUB_MAIN_VIEW = "group.mainview", --亲友圈桌子页面 | |||
PHP_CLUB_ACTIVE_GAME = "group.modifGame", --激活游戏 | |||
PHP_CLUB_ACTIVE_GAME_RULE = "group.modifGameRule", --激活玩法 | |||
PHP_CLUB_ROOMLIST = "group.roomList", --房间列表 | |||
PHP_CLUB_BAOJIAN_SET_STYLE = "group.batchRuleSetup", --包间批量更新 | |||
PHP_CLUB_SHANG_BAO = "paihang.uploadpaihang", --上报排名 | |||
PHP_CLUB_CHECK_RANK = "paihang.getpaihang", --排行榜查询 | |||
--排名赛 | |||
PHP_CLUB_ALL_RANK_LIST = "group.allRankingList", --排名赛排名 | |||
PHP_CLUB_TEAM_RANK_LIST = "group.warRankingList", --战队/小队排名 | |||
PHP_CLUB_WAR_RANKING_LIST = "group.levelLog", --战队/亲友圈等级提升记录 | |||
PHP_CLUB_LEVEL_UPGRADE = "group.levelUpgrade", --等级提升 | |||
PHP_CLUB_WAR_MEMBER = "group.warMember", --排名赛管理 | |||
PHP_CLUB_WAR_NUM_APPLY = "group.exceptWarnum", --排名赛异常补偿/异常处罚(可批量) | |||
PHP_CLUB_SETMWARNUM = "group.setMWarnum", --排名赛:指派出赛/上报排名 | |||
PHP_CLUB_WARMEMBERSTATUS = "group.warMemberStatus", --成员设置 | |||
PHP_CLUB_CONTENT_LOG = "group.getArenaContentLog", --比赛记录/贡献记录 | |||
PHP_CLUB_WARNUM_APPLY = "group.warnumApply", --排名分申请 | |||
PHP_CLUB_WARNUM_APPLY_LIST = "group.warnumApplyList", --排名赛申请 | |||
PHP_CLUB_WARNUM_APPLY_STATUS = "group.warnumApplyStatus", --排名赛申请(列表)审批处理 | |||
PHP_CLUB_BAOJIAN_TONGJI = "group.getWarDateStatList", --排名赛包间局数统计 | |||
PHP_CLUB_MATCH_CHOUJIANG = "group.warRewardToken", --排名赛抽奖 | |||
PHP_CLUB_COPY_CLUB = "group.copyGroupImportMember", --复制群关系导入至排名赛群 | |||
PHP_CLUB_GRANT_SET = "group.grantPower", --管理员权限管理 | |||
PHP_CLUB_MATCH_TONGJI = "group.getArenaDate", --赛事统计 | |||
--union | |||
PHP_CLUB_UNION_SWITCH = "group.unionSwitch", --联盟开关 | |||
PHP_CLUB_GET_UNION_MASTER_INFO = "group.getUnionMasterInfo", --合盟获取主盟信息 | |||
PHP_CLUB_SEARCH_MATER_UNION = "group.applyUnionBefore", --查询主盟信息 | |||
PHP_CLUB_APPLY_MATER_UNION = "group.applyUnion", --申请加入主盟 | |||
PHP_CLUB_MATER_UNION_MESSAGE = "group.applyUnionList", --主盟消息获取 | |||
PHP_CLUB_MATER_UNION_MESSAGE_JUDGE = "group.applyUnionStatus", --主盟消息审批 | |||
PHP_CLUB_MATER_UNION_LIST = "group.unionList", --联盟亲友圈列表 | |||
PHP_CLUB_SLAVE_UNION_DISSMISS = "group.reUnion", --合盟发起解散联盟关系 | |||
PHP_CLUB_MASTER_UNION_SETUP = "group.unionSetup", --盟主(管理员)操作设置(贡献分配,冻结,解除关心,取消冻结) | |||
PHP_CLUB_UNION_BELONG = "group.belongInfo", --亲友圈归属信息 | |||
PHP_CLUB_LOCAL_UNION = "group.localUnions", --亲友圈归属信息-所在亲友圈 | |||
PHP_CLUB_BELONG_SET = "group.belongSet", --亲友圈归属信息-更换设置 | |||
PHP_CLUB_UNION_RECORD = "group.getUnionArenaDate", --联盟记录 | |||
PHP_CLUB_UNION_DETAIL = "group.getUnionStatDetail", --副盟贡献详情 | |||
--[[/** | |||
* 用户创建房间 | |||
* <pre> | |||
* 请求: {@code ClubCreateRoomRequest} | |||
* 返回:- 创建成功返回 0x0205 | |||
* 返回:- 若此时用户已经在房间里面玩牌,则返回 0x0117 | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_CLUB_CREATEROOM = 0x0204, | |||
--[[/** | |||
* 茶馆创建房间结果返回 | |||
* <pre> | |||
* 推送: {@code ClubCreateRoomResponse} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_CLUB_CREATEROOM_RESPONSE = 0x0205, | |||
--[[/** | |||
* 茶馆加入房间 | |||
* <pre> | |||
* 推送: {@code ClubJoinRoomRequest} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_CLUB_JOINROOM_REQUEST = 0x0206, | |||
--[[/** | |||
* 茶馆加入房间返回结果 | |||
* <pre> | |||
* 推送: {@code ClubJoinRoomResponse} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_CLUB_JOINROOM_RESPONSE = 0x0207, | |||
--[[/** | |||
* 茶馆游戏未开始踢人协议 | |||
* <pre> | |||
* 推送: {@code ClubKickRequest} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_CLUB_KICK_REQUEST = 0x0208, | |||
--[[/** | |||
* 茶馆踢人结果协议 | |||
* <pre> | |||
* 推送: {@code ClubKickResponse} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_CLUB_KICK_RESPONSE = 0x0209, | |||
--[[/** | |||
* 同时被踢玩家收到被踢协议 | |||
* <pre> | |||
* 推送: {@code ClubOtherKickedResponse} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_CLUB_OTHER_KICKED_RESPONSE = 0x8006, | |||
--[[/** | |||
* 茶馆解散房间协议 | |||
* <pre> | |||
* 推送: {@code ClubDismissRequest} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_CLUB_DISMISS_REQUEST = 0x020a, | |||
--[[/** | |||
* 茶馆解散房间结果协议 | |||
* <pre> | |||
* 推送: {@code ClubDismissResponse} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_CLUB_DISMISS_RESPONSE = 0x020b, | |||
--[[/** | |||
* 俱乐部禁止同桌结果 | |||
* <pre> | |||
* 推送: {@code ClubNotSameDeskResponse} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_CLUB_NOTSAMEDESK_RESPONSE = 0x020c, | |||
} | |||
return ClubCmd |
@@ -0,0 +1,257 @@ | |||
local Cmd = require("luaScript.Protocol.Club.ClubCmd") | |||
local ClubDefine = {} | |||
--推送消息类型定义 | |||
ClubDefine.PUSH = { | |||
changeBaoJian = 10024, --更新包间 | |||
changeBaoJianSet = 10029, --包间设置 | |||
clubJieSan = 10014, --解散茶馆 | |||
changeClubName = 10020, -- 修改茶馆名 | |||
dongJieClub = 10015, --茶馆状态修改冻结 | |||
jieDongClub = 10010, --茶馆状态修改解冻 | |||
kickClubPlayer = 10011, --踢出茶馆 | |||
changeClubSet = 10027, --修改茶馆设置 隐私 微信分享 茶馆模式 | |||
changePlayer = 10022, -- 修改成员 | |||
applyClubSuccess = 10016, -- 申请加入茶馆成功通知 | |||
changeRoom = 10021, --更新房间数据 | |||
changeClubNotice = 10026, --更新公告 | |||
changeClubTableNum = 10023, --在线桌数 | |||
message = 10012, --消息推送/主盟收到副盟加入通知 | |||
invite = 10050, --邀请好友 | |||
dayingjiaset = 10040, --大赢家设置 | |||
changeClubBg = 10081, --亲友圈背景设置 | |||
cancelCopartner = 10043, --取消合伙人通知 | |||
gameActive = 10041, --游戏激活推送 | |||
setAllBaoJian = 10042, --设置所有包间 | |||
updateUnionMasterState = 10044, --刷新主盟管理-亲友圈列表状态 | |||
updateUnionSlaveState = 10045, --刷新副盟管理-状态 | |||
} | |||
ClubDefine.heHuoRenText = "合伙人" | |||
ClubDefine.Error = { | |||
[Cmd.PHP_CLUB_ADD_PLAYER] = { | |||
[1024] = "玩家ID不存在,请重新输入", | |||
[1020] = "玩家ID不存在,请重新输入", | |||
[1037] = "玩家已在"..PLN.CLUB_NAME.."!" | |||
}, | |||
[Cmd.PHP_CLUB_CREATE] = { | |||
[1044] = PLN.CLUB_NAME.."创建失败,名字存在特殊字符", | |||
[1018] = PLN.CLUB_NAME.."创建失败,"..PLN.CLUB_NAME.."个数已达上限!", | |||
}, | |||
[Cmd.PHP_CLUB_CHANGE_APPLY_STATUS] = { | |||
[1021] = "已经同意申请!", | |||
}, | |||
[Cmd.PHP_CLUB_PLAYER_LIST] = { | |||
[1011] = "非"..PLN.CLUB_NAME.."成员或已被踢出"..PLN.CLUB_NAME.."!", | |||
[1014] = PLN.CLUB_NAME.."不存在或已经解散!", | |||
}, | |||
[Cmd.PHP_CLUB_UPDATE_NOTICE] = { | |||
[1031] = PLN.CLUB_NAME.."更新公告失败,包含敏感字符!", | |||
}, | |||
[Cmd.PHP_CLUB_SET] = { | |||
[1044] = "名称中含有特殊字符,无法识别。请重新输入常规文字!" | |||
}, | |||
[Cmd.PHP_CLUB_MEMBER_SET] = { | |||
[1014] = PLN.CLUB_NAME.."不存在或已经解散!", | |||
}, | |||
[Cmd.PHP_CLUB_WARMEMBERSTATUS] = { | |||
[200] = "操作成功!", | |||
[1210] = "没有权限,请联系客服!", | |||
}, | |||
[Cmd.PHP_CLUB_ACTIVE_GAME_RULE] = { | |||
[200] = "操作成功!", | |||
}, | |||
[Cmd.PHP_CLUB_COPY_CLUB] = { | |||
[200] = "复制成功!", | |||
}, | |||
[Cmd.PHP_CLUB_GRANT_SET] = { | |||
[200] = "操作成功!", | |||
}, | |||
[Cmd.PHP_CLUB_UNION_SWITCH] = { | |||
[200] = "操作成功!", | |||
[201] = "您已开启主盟权限!", | |||
[202] = "您已开启副盟权限!", | |||
[1026] = "无管理员权限", | |||
[1110] = "PLN.CLUB_NAME..ID不正确,或此"..PLN.CLUB_NAME.."无权限!", | |||
[1121] = "本"..PLN.CLUB_NAME.."名下玩家排名分不为0,或存在队长,或已有对局,无法开启权限!", | |||
[1129] = "本"..PLN.CLUB_NAME.."当前有玩家正在玩牌, 无法设置副盟!", | |||
[1122] = "本"..PLN.CLUB_NAME.."贡献值不为0,无法开启权限!", | |||
[1131] ="无法同时开启主盟权限和合盟权限", | |||
[1132] = "请勾选同意下方联盟合作协议,即可开启权限哦。", | |||
[1133] = "请勾选同意下方联盟合作协议,即可开启权限哦。", | |||
[1134] = "开启主盟失败,当前"..PLN.CLUB_NAME.."已是合盟!", | |||
[1135] = "开启合盟失败,当前"..PLN.CLUB_NAME.."已是主盟!", | |||
[1136] = "请先解除所有"..PLN.CLUB_NAME.."的合盟关系后,再进行操作!", | |||
[1137] = "关闭合盟权限失败,请到【联盟管理】点击解散联盟,再关闭!" | |||
}, | |||
[Cmd.PHP_CLUB_SEARCH_MATER_UNION] = { | |||
[0] = "请输入其它茶馆ID", | |||
[1110] = PLN.CLUB_NAME.."ID不正确,或此"..PLN.CLUB_NAME.."无权限!", | |||
[1121] = "本"..PLN.CLUB_NAME.."名下玩家排名分不为0,或存在队长,或已有对局,无法开启权限!", | |||
[1122] = "本"..PLN.CLUB_NAME.."贡献值不为0,无法开启权限!", | |||
[1019] = "查询太频繁,请稍候再试", | |||
[1026] = "无管理员权限", | |||
[1124] = "请先开启合盟权限!", | |||
[1125] = "您已加入该主盟", | |||
[1126] = "您已加入其它联盟", | |||
}, | |||
[Cmd.PHP_CLUB_APPLY_MATER_UNION] = { | |||
[200] = "申请成功,请等待盟主同意!", | |||
[1026] = "无管理员权限", | |||
[1122] = "本"..PLN.CLUB_NAME.."贡献值不为0,无法申请加入了", | |||
[1124] = "请先开启合盟权限!", | |||
[1125] = "您已加入该主盟", | |||
[1126] = "您已加入其它联盟", | |||
}, | |||
[Cmd.PHP_CLUB_MATER_UNION_MESSAGE] = { | |||
[1026] = "无管理员权限", | |||
[1123] = "请先开启主盟权限!", | |||
[1125] = "您已加入该主盟", | |||
[1126] = "您已加入其它联盟", | |||
}, | |||
[Cmd.PHP_CLUB_SLAVE_UNION_DISSMISS] = { | |||
[200] = "操作成功!", | |||
[1026] = "无管理员权限", | |||
[1151] = "排名总分不为0,请先上报排名后再进行解除操作!!", | |||
}, | |||
[Cmd.PHP_CLUB_MASTER_UNION_SETUP] = { | |||
[200] = "操作成功!", | |||
[1151] = "该"..PLN.CLUB_NAME.."排名总分不为0,请先上报排名后再进行解除操作!", | |||
}, | |||
[Cmd.PHP_CLUB_BELONG_SET] = { | |||
[200] = "操作成功!", | |||
}, | |||
[Cmd.PHP_CLUB_SETMWARNUM] = { | |||
[200] = "处理成功!", | |||
}, | |||
[Cmd.PHP_CLUB_WAR_NUM_APPLY] = { | |||
[200] = "处理成功!", | |||
}, | |||
[Cmd.PHP_CLUB_MATER_UNION_MESSAGE_JUDGE] = { | |||
[200] = "处理成功!", | |||
[1121] = "本"..PLN.CLUB_NAME.."名下玩家排名分不为0,或存在队长,或已有对局,无法开启权限!", | |||
[1122] = "本"..PLN.CLUB_NAME.."贡献值不为0,无法开启权限!", | |||
[1124] = "该"..PLN.CLUB_NAME.."已关闭副盟权限!", | |||
[1026] = "无操作权限", | |||
[1123] = "请先开启主盟权限!", | |||
[1141] = "该"..PLN.CLUB_NAME.."申请不存在,或已解散!", | |||
[1143] = "该申请已处理成功!", | |||
[1128] = "该副盟已加入其它主盟!", | |||
[1024] = "此申请人玩家ID不存在, 无需审批", | |||
[1151] = "该"..PLN.CLUB_NAME.."排名总分不为0,请先上报排名后再进行解除操作!", | |||
}, | |||
[Cmd.PHP_CLUB_SHANG_BAO] = { | |||
[200] = "上报成功,请在排行榜查看排名!", | |||
}, | |||
[Cmd.PHP_CLUB_CHECK_RANK] = { | |||
[101] = "参数错误(101)", | |||
} | |||
} | |||
ClubDefine.Job = { | |||
Member = 1, --成员 | |||
Manager = 2, --管理员 | |||
Creator = 3, --创始人 | |||
Copartner = 4, --合伙人 | |||
LevelOneCopartner = 5, --一级合伙人(队长) | |||
LevelTwoCopartner = 6, --二级合伙人(小队) | |||
LevelThreeCopartner = 7, --三级合伙人(小组长) | |||
} | |||
ClubDefine.Role = { | |||
[1] = "成 员", | |||
[2] = "管理员", | |||
[3] = PLN.CLUB_CREATOR_DESC2, | |||
[4] = ClubDefine.heHuoRenText, | |||
[5] = "一级"..ClubDefine.heHuoRenText, | |||
[6] = "二级"..ClubDefine.heHuoRenText, | |||
[7] = "三级"..ClubDefine.heHuoRenText, | |||
} | |||
ClubDefine.RoleNew = { | |||
[1] = "成 员", | |||
[2] = "管理员", | |||
[3] = PLN.CLUB_CREATOR_DESC2, | |||
[4] = ClubDefine.heHuoRenText, | |||
[5] = "队长", | |||
[6] = "小队长", | |||
[7] = "小组长", | |||
} | |||
--界面状态机,有利于数据分割,多模式区分,以及精准的刷新控制。 | |||
ClubDefine.PlayListType = { | |||
--普通场 | |||
NORMAL_MEMBER = 0, --成员列表 | |||
INVITE_ONLINE = 1, --亲友圈邀请 | |||
--比赛场 | |||
MATCH_MEMBER = 2, --比赛场成员 | |||
MATCH_RECORD = 3, --比赛场记录 | |||
MATCH_LV_1_COPARTNER_MEMBER = 4, --1级合伙人下属成员 | |||
MATCH_LV_2_COPARTNER_MEMBER = 5, --2级合伙人下属成员 | |||
MATCH_LV_1_COPARTNER_RECORD = 6, --1级合伙人下属成员记录 | |||
MATCH_LV_2_COPARTNER_RECORD = 7, --2级合伙人下属成员记录 | |||
MATCH_RANK = 8, --排行榜 | |||
MATCH_ADJUST_MEMBER = 9, --调配成员 | |||
MATCH_LV_1_ADJUST_MEMBER = 10, --1j调配成员 | |||
MATCH_LV_2_ADJUST_MEMBER = 11, --2j调配成员 | |||
SEARCH_PLAYER = 12, --搜索 | |||
--排名赛 | |||
ALL_PEOPLE_MATCH_RANK = 13, --排名赛排名 | |||
ALL_PEOPLE_MATCH_TEAM_RANK = 14, --战队排名 | |||
ALL_PEOPLE_MATCH_TEAM_LEVEL = 15, --战队等级 | |||
ALL_PEOPLE_MATCH_MANAGER = 16, --排名赛管理 | |||
ALL_PEOPLE_MATCH_TEAM_LIST = 17, --战队列表 | |||
ALL_PEOPLE_MATCH_TEAM_LIST_TEAM = 18, --队长列表 | |||
ALL_PEOPLE_MATCH_SET_MEMBER = 19, --调配成员 | |||
ALL_PEOPLE_MATCH_LV_1_COPARTNER_MEMBER = 21, --队长下属成员 | |||
ALL_PEOPLE_MATCH_LV_2_COPARTNER_MEMBER = 22, --小队长下属成员 | |||
ALL_PEOPLE_MATCH_LV_3_COPARTNER_MEMBER = 23, --小组长下属成员 | |||
--合盟模式(可以和其他模式共存) | |||
UNION_CLUB_LIST = 20, --合盟亲友圈列表 | |||
} | |||
--{0:全部, 1:加减记录, 2比赛记录, 3赠送记录, 11:调整红花记录} | |||
ClubDefine.RedFlowRecordType = { | |||
ALL = 0, | |||
SUM_SUB = 1, | |||
PAI_JU = 2, | |||
PRIZE = 3, | |||
ADJUST = 11, | |||
} | |||
ClubDefine.MATCH_SWITCH = { | |||
SERVER_CLOSE = 0, --后台关闭 | |||
CLIENT_CLOSE = 1, --比赛场关闭 | |||
CLIENT_OPEN = 2, --比赛场开启 | |||
PEOPLE_MATCH_SEVER_CLOSE = 10, --后台关闭 | |||
PEOPLE_MATCH_CLOSE = 11, --排名赛关闭 | |||
PEOPLE_MATCH_OPEN = 12, --排名赛开启 | |||
} | |||
ClubDefine.BaoJianType = { | |||
Normal = 0, --单包间模式 | |||
Multiple = 1,--混合多包间模式 | |||
ManyRooms = 2,--子游戏多包间模式 | |||
} | |||
ClubDefine.ClubMessage = { | |||
PLAYER_APPLY = 0, --玩家申请 | |||
TEAMER_APPLY = 3, --队长申请 | |||
ALL_PEOPLE_MATCH_APPLY = 4, --排名赛申请 | |||
AWARD_APPLY = 2, --奖励申请 | |||
CLUB_MESSAGE = 1, --亲友圈消息 | |||
} | |||
--[[ | |||
服务器posnumber是无符号short,最多支持到32767个桌子, | |||
一个包间100个桌子算,大约是32767/100 = 327个包间,约等于327/10 = 32个游戏左右 | |||
]] | |||
--最大支持游戏个数 | |||
ClubDefine.MaxGameCount = 32 | |||
--支持包间的个数 | |||
ClubDefine.BaoJianCount = 10 | |||
--包间个数支持的椅子最大值 | |||
ClubDefine.TableCountMax = 100 | |||
return ClubDefine |
@@ -0,0 +1,107 @@ | |||
--茶馆创建房间 | |||
ClubCreateRoomRequest = defClass("ClubCreateRoomRequest" | |||
--游戏id | |||
, defVar("gameid", VT_Short, -1) | |||
--茶馆标识 | |||
, defVar("groupId", VT_Int, 0) | |||
--茶馆桌子序号 | |||
, defVar("groupIndex", VT_Short, -1) | |||
--茶馆创建者uid | |||
, defVar("groupUid", VT_Int, 0) | |||
--游戏局数 | |||
, defVar("gameNum", VT_Short, -1) | |||
--游戏信息,同游戏创建参数 | |||
, defVar("gameInfo", VT_String, "") | |||
--发起创建的用户信息 | |||
, defVar("usrinfo", VT_String, "") | |||
--茶馆成员人数 | |||
, defVar("groupMemNum", VT_Short, -1) | |||
) | |||
--茶馆创建房间返回结果 | |||
ClubCreateRoomResponse = defClass("ClubCreateRoomResponse" | |||
--返回码 | |||
, defVar("ret", VT_Short, -1) | |||
, defVar("showTableId", VT_Int, -1) | |||
) | |||
--茶馆加入房间 | |||
ClubJoinRoomRequest = defClass("ClubJoinRoomRequest" | |||
--游戏id | |||
, defVar("gameid", VT_Short, "") | |||
--房间号 | |||
, defVar("tableid", VT_Int, 0) | |||
--茶馆标识 | |||
, defVar("grouId", VT_Int, 0) | |||
--茶馆桌子序号 | |||
, defVar("groupIndex", VT_Short, "") | |||
--用户信息 | |||
, defVar("usrinfo", VT_String, "") | |||
) | |||
--茶馆加入房间返回结果 | |||
ClubJoinRoomResponse = defClass("ClubJoinRoomResponse" | |||
--返回码 | |||
, defVar("ret", VT_Short, -1) | |||
) | |||
--php推送消息 | |||
ClubGetPhpMessage = defClass("ClubGetPhpMessage" | |||
--消息内容及格式 php client具体协商 | |||
, defVar("message", VT_String, "") | |||
) | |||
--茶馆游戏未开始踢人协议 | |||
ClubKickRequest = defClass("ClubKickRequest" | |||
--游戏id | |||
, defVar("gameid", VT_Short, "") | |||
--房间号 | |||
, defVar("tableid", VT_Int, 0) | |||
--茶馆id | |||
, defVar("groupid", VT_Int, 0) | |||
--被踢玩家uid | |||
, defVar("beKickUid", VT_Int, 0) | |||
) | |||
--茶馆踢人结果协议 | |||
ClubKickResponse = defClass("ClubKickResponse" | |||
--返回码 | |||
, defVar("result", VT_Short, -1) | |||
) | |||
--同时被踢玩家收到被踢协议 | |||
ClubOtherKickedResponse = defClass("ClubOtherKickedResponse" | |||
--被踢玩家uid | |||
, defVar("beKickUid", VT_Int, 0) | |||
--被踢原因 | |||
, defVar("kickType", VT_Short, "") | |||
) | |||
--茶馆解散房间协议 | |||
ClubDismissRequest = defClass("ClubDismissRequest" | |||
--游戏id | |||
, defVar("gameid", VT_Short, "") | |||
--房间号 | |||
, defVar("tableid", VT_Int, 0) | |||
--茶馆id | |||
, defVar("groupid", VT_Int, 0) | |||
) | |||
--茶馆解散房间结果协议 | |||
ClubDismissResponse = defClass("ClubDismissResponse" | |||
--返回码 | |||
, defVar("result", VT_Short, -1) | |||
) | |||
--茶馆禁止同桌返回结果 | |||
ClubNotSameDeskResponse = defClass("ClubNotSameDeskResponse" | |||
--返回码 | |||
, defVar("ret", VT_Short, -1)--取值同加入房间 | |||
--被禁止玩家uid | |||
, defVar("forbidUid", VT_Int, 0) | |||
--玩家信息 json格式 | |||
, defVar("userInfo", VT_String, "") | |||
--俱乐部GPS限制距离,0为不限制,其他代表限制的米数 | |||
, defVar("gpsLimit", VT_Int, 0) | |||
) |
@@ -0,0 +1,220 @@ | |||
require("luaScript.Protocol.ProtocolCommon") | |||
require("luaScript.Protocol.Club.ClubProtocalMessage") | |||
local ClubProtocol = class("ClubProtocol" , require("luaScript.Protocol.Protocol")) | |||
local ClubCmd = require("luaScript.Protocol.Club.ClubCmd") | |||
-- 创建茶馆房间结果,成功或者失败 | |||
function ClubProtocol:onClubCreateRoomRequest(status, response) | |||
logD("ClubProtocol:onClubCreateRoomRequest(), ", table.tostring(response)) | |||
--如果是点了再来一局才去拉取数据 | |||
local againbol,wanfa = getIsAgainGamebol() | |||
if wanfa ~= "" and response.ret == 0 then | |||
setGameRoomId(response.showTableId) | |||
app.club_php:clubInviteSameTable() | |||
end | |||
--app.waitDialogManager:closeWaitNetworkDialog(); | |||
app.waitDialogManager:closeAllNetWait(); | |||
-- 成功后直接进入房间 | |||
--创建房间失败提示游戏开始禁止加入游戏时,主动重新创建一个房间,并刷新茶馆桌子 | |||
if response.ret ~= 0 then | |||
showTooltip(GAME_CLUB_CREATE_ROOM_RESULT[response.ret] or tostring(response.ret)); | |||
logD("ClubProtocol:onClubCreateRoomRequest() createFail, ", tostring(response.ret)) | |||
if response.ret == 4 then | |||
if app.club_php.clubID and app.club_php.clubID~=0 then | |||
app.club_php:requestClubHome(app.club_php.clubID) | |||
end | |||
app.club:dispatchEvent({name = GAME_EVENT.CLUB_CREATE_ERR}) | |||
end | |||
end | |||
end | |||
-- 加入茶馆房间结果,成功或者失败 | |||
function ClubProtocol:onClubJoinRoomResponse(status, response) | |||
logD("ClubProtocol:onClubJoinRoomResponse(), ", table.tostring(response)) | |||
logD(table.tostring(response)) | |||
--app.waitDialogManager:closeWaitNetworkDialog(); | |||
app.waitDialogManager:closeAllNetWait(); | |||
if response.ret == 1 then | |||
if self.clubCreateRoomData ~= nil then | |||
--房间解散时,加入失败,就直接发送创建房间 | |||
self:requesetCreateRoomInClub(self.clubCreateRoomData); | |||
--清空创建房间数据 | |||
self.clubCreateRoomData = nil; | |||
return; | |||
end | |||
end | |||
-- 成功后直接进入房间 | |||
if response.ret ~= 0 then | |||
showTooltip(GAME_CLUB_JOIN_ROOM_RESULT[response.ret] or tostring(response.ret)); | |||
end | |||
end | |||
--茶馆踢人结果协议 | |||
function ClubProtocol:onClubKickResponse(status,response) | |||
logD("ClubProtocol:onClubKickResponse(), ", table.tostring(response)) | |||
app.waitDialogManager:closeWaitNetworkDialog(); | |||
showTooltip(GAME_CLUB_KICK_RESULT[response.result] or tostring(response.result)); | |||
self:dispatchEvent({name = "onClubKickResponse"}); | |||
end | |||
--同时被踢玩家收到被踢协议 | |||
function ClubProtocol:onClubOtherKickedResponse(status,response) | |||
logD("ClubProtocol:onClubOtherKickedResponse(), ", table.tostring(response)) | |||
app.waitDialogManager:closeWaitNetworkDialog(); | |||
showTooltip("您已被管理员踢出房间") | |||
self:dispatchEvent({name = "onClubOtherKickedResponse"}); | |||
end | |||
--茶馆解散房间结果协议 | |||
function ClubProtocol:onClubDismissResponse(status,response) | |||
logD("ClubProtocol:onClubDismissResponse(), response = ", table.tostring(response)) | |||
app.waitDialogManager:closeWaitNetworkDialog(); | |||
showTooltip(GAME_CLUB_DISMISS_RESULT[response.result] or tostring(response.result)); | |||
self:dispatchEvent({name = "onClubDismissResponse"}); | |||
end | |||
--申请创建房间 | |||
function ClubProtocol:requesetCreateRoomInClub(request) | |||
setIsRoomGamedata(nil) | |||
setisContinueRoomGamedata(nil) | |||
setisContinueRoomGamebol(false) | |||
--清空抽奖数据 | |||
dd.IGameOverAward.setAwardData(nil) | |||
checkSubGameFiles(request.gameid, function() | |||
-- 为了收到服务器返回的结果时能正确接收房间消息 | |||
-- 这里应该先加载房间协议 | |||
local gameInfo = {} | |||
local gameType = nil | |||
if request.gameInfo then | |||
gameInfo = json.decode(request.gameInfo) | |||
gameType = gameInfo.gamerule or 0 | |||
end | |||
--如果是合盟 | |||
local clubInfo = app.club_php.clubList[tonumber(request.groupId)] | |||
if clubInfo then | |||
if clubInfo.unionType == 2 then | |||
request.groupId = tonumber(clubInfo.unionGid);--茶馆标识 | |||
request.groupUid = tonumber(clubInfo.unionOwner);--茶馆标识 | |||
gameInfo.clubId = tonumber(clubInfo.unionGid);--茶馆标识 | |||
request.gameInfo = json.encode(gameInfo) | |||
elseif clubInfo.unionType == 1 then | |||
request.groupUid = tonumber(clubInfo.ownerId);--茶馆标识 | |||
end | |||
end | |||
logD("ClubProtocol:requesetCreateRoomInClub(), request = ", table.tostring(request)) | |||
app:changeGameProtocol(request.gameid or 0,gameType); | |||
app.waitDialogManager:showWaitNetworkDialog(); | |||
self:sendResponse{cmd = ClubCmd.GAME_COMMAND_CLUB_CREATEROOM , sender = request}; | |||
end) | |||
end | |||
-- 申请加入房间 | |||
function ClubProtocol:requestJoinRoomInClub(request, createRoomRequst) | |||
logD("ClubProtocol:requestJoinRoomInClub(), request = ", table.tostring(request)) | |||
-- 进房之前先检查文件完整性 | |||
checkSubGameFiles(request.gameid, function() | |||
app:changeGameProtocol(request.gameid or 0,request.gamerule or 0); | |||
--记录创建房间数据 | |||
self.clubCreateRoomData = createRoomRequst; | |||
--如果是合盟 | |||
local clubInfo = app.club_php.clubList[tonumber(request.grouId)] | |||
if clubInfo then | |||
if clubInfo.unionType == 2 then | |||
request.grouId = tonumber(clubInfo.unionGid);--茶馆标识 | |||
end | |||
end | |||
app.waitDialogManager:showWaitNetworkDialog(); | |||
self:sendResponse{cmd = ClubCmd.GAME_COMMAND_CLUB_JOINROOM_REQUEST , sender = request}; | |||
end) | |||
end | |||
--茶馆中解散房间请求 | |||
function ClubProtocol:requestDismissInClub(request) | |||
logD("ClubProtocol:requestDismissInClub(), ", table.tostring(request)) | |||
app.waitDialogManager:showWaitNetworkDialog(); | |||
self:sendResponse{cmd = ClubCmd.GAME_COMMAND_CLUB_DISMISS_REQUEST , sender = request}; | |||
end | |||
--茶馆中踢人请求 | |||
function ClubProtocol:requestKickInClub(request) | |||
logD("ClubProtocol:requestKickInClub(), ", table.tostring(request)) | |||
app.waitDialogManager:showWaitNetworkDialog(); | |||
self:sendResponse{cmd = ClubCmd.GAME_COMMAND_CLUB_KICK_REQUEST , sender = request}; | |||
end | |||
-- 茶馆禁止同桌结果 | |||
function ClubProtocol:onClubNotSameDeskResponse(status, response) | |||
logD("ClubProtocol:onClubNotSameDeskResponse(), ", table.tostring(response)) | |||
app.waitDialogManager:closeWaitNetworkDialog(); | |||
-- 成功后直接进入房间 | |||
if response.ret == 16 then | |||
self:dispatchEvent({name = "onClubNotSameDeskResponse",uid = response.forbidUid,userInfo = response.userInfo}); | |||
elseif response.ret == 19 then | |||
self:dispatchEvent({name = GAME_EVENT.CLUB_GPS_DISTANCE,uid = response.forbidUid,userInfo = response.userInfo,gpsLimit = response.gpsLimit}); | |||
end | |||
end | |||
function ClubProtocol:ctor(net) | |||
ClubProtocol.super.ctor(self , net); | |||
--加入房间数据 | |||
self.clubCreateRoomData = nil; | |||
--发送 | |||
-- 创建房间 | |||
self:defMsgFunc{name = "clubCreateRoomRequest" , cmd = ClubCmd.GAME_COMMAND_CLUB_CREATEROOM, sender = ClubCreateRoomRequest}; | |||
-- 加入房间 | |||
self:defMsgFunc{name = "clubJoinRoomRequest" , cmd = ClubCmd.GAME_COMMAND_CLUB_JOINROOM_REQUEST, sender = ClubJoinRoomRequest}; | |||
-- 茶馆游戏未开始时踢人 | |||
self:defMsgFunc{name = "clubKickRequest" , cmd = ClubCmd.GAME_COMMAND_CLUB_KICK_REQUEST, sender = ClubKickRequest}; | |||
-- 茶馆解散房间 | |||
self:defMsgFunc{name = "ClubDismissRequest" , cmd = ClubCmd.GAME_COMMAND_CLUB_DISMISS_REQUEST, sender = ClubDismissRequest}; | |||
--接收 | |||
-- 推送创建房间结果(正常进入)如果进房成功,服务器会快速分配桌子给玩家,分配成功返回进入桌子成功消息 RoomCmd.GAME_COMMAND_LOGIN_GAME_SUCCESS | |||
self:defPushMsg{cmd = ClubCmd.GAME_COMMAND_CLUB_CREATEROOM_RESPONSE , reader = ClubCreateRoomResponse, func = handler(self , self.onClubCreateRoomRequest)}; | |||
-- 推送加入房间结果 | |||
self:defPushMsg{cmd = ClubCmd.GAME_COMMAND_CLUB_JOINROOM_RESPONSE , reader = ClubJoinRoomResponse, func = handler(self , self.onClubJoinRoomResponse)}; | |||
-- 茶馆踢人结果协议 | |||
self:defPushMsg{cmd = ClubCmd.GAME_COMMAND_CLUB_KICK_RESPONSE , reader = ClubKickResponse, func = handler(self , self.onClubKickResponse)}; | |||
-- 同时被踢玩家收到被踢协议 | |||
self:defPushMsg{cmd = ClubCmd.GAME_COMMAND_CLUB_OTHER_KICKED_RESPONSE , reader = ClubOtherKickedResponse, func = handler(self , self.onClubOtherKickedResponse)}; | |||
-- 茶馆解散房间结果 | |||
self:defPushMsg{cmd = ClubCmd.GAME_COMMAND_CLUB_DISMISS_RESPONSE , reader = ClubDismissResponse, func = handler(self , self.onClubDismissResponse)}; | |||
-- 茶馆禁止同桌结果 | |||
self:defPushMsg{cmd = ClubCmd.GAME_COMMAND_CLUB_NOTSAMEDESK_RESPONSE , reader = ClubNotSameDeskResponse, func = handler(self , self.onClubNotSameDeskResponse)}; | |||
end | |||
return ClubProtocol; |
@@ -0,0 +1,18 @@ | |||
local CoinCmd = { | |||
--[[/** | |||
* 金币场请求进入 | |||
* <pre> | |||
* 推送: {@code EnterCoinRequest} | |||
* </pre> | |||
*/--]] | |||
Enter_Coin_Room_Request = 0x0113, | |||
--[[/** | |||
* 金币场请求进入结果 | |||
* <pre> | |||
* 推送: {@code EnterCoinResponse} | |||
* </pre> | |||
*/--]] | |||
Enter_Coin_Room_Response = 0x0112 | |||
} | |||
return CoinCmd |
@@ -0,0 +1,18 @@ | |||
local message = {}; | |||
message.EnterCoinResponse = defClass("EnterCoinResponse" | |||
-- 供查询的游戏列表 | |||
, defVar("ret", VT_Short, 0) | |||
) | |||
message.EnterCoinRequest = defClass("EnterCoinRequest" | |||
-- 供查询的游戏列表 | |||
, defVar("gameid", VT_Short, 0) | |||
-- 房间ID | |||
, defVar("serverLevel", VT_Short, 0) | |||
-- 用户信息 | |||
, defVar("userInfo", VT_String, "") | |||
) | |||
return message; |
@@ -0,0 +1,9 @@ | |||
--- 金币场相关php命令字 | |||
local PHPCmd = {} | |||
-- 获取游戏等级配置 | |||
PHPCmd.PHP_GAME_SERVER_CONFIG = "system.getLevelInfo" | |||
PHPCmd.PHP_DAY_FULI = "tasks.getList" | |||
PHPCmd.PHP_DAY_GET_TASK_PRIZE = "tasks.getPrize" | |||
return PHPCmd |
@@ -0,0 +1,31 @@ | |||
local Protocol = require("luaScript.Protocol.Protocol") | |||
local CoinProtocol = class("CoinProtocol", Protocol) | |||
local CoinMessage = import("luaScript.Protocol.Coin.CoinMessage") | |||
local CoinCmd = import("luaScript.Protocol.Coin.CoinCmd") | |||
--- CoinProtocol:requestEnterCoinRoom 请求进入金币场 | |||
-- @param data | |||
function CoinProtocol:requestEnterCoinRoom(data) | |||
-- app.waitDialogManager:showWaitNetworkDialog() | |||
local request = CoinMessage.EnterCoinRequest:new() | |||
request.gameid = data.gameid | |||
request.serverLevel = data.serverLevel | |||
request.userInfo = data.userInfo | |||
app.user.serverLevel = data.serverLevel | |||
logD("CoinProtocol:requestEnterCoinRoom :", table.tostring(request)) | |||
self:sendResponse {cmd = CoinCmd.Enter_Coin_Room_Request, sender = request} | |||
end | |||
--- CoinProtocol:onEnterCoinResponse 请求进入金币场回复 | |||
-- @param status | |||
-- @param response | |||
function CoinProtocol:onEnterCoinResponse(status, response) | |||
logD("CoinProtocol:onEnterCoinResponse(), ", table.tostring(response)) | |||
-- app.waitDialogManager:closeWaitNetworkDialog() | |||
self:dispatchEvent({name = "onEnterCoinResponse", response = response}) | |||
end | |||
function CoinProtocol:ctor() | |||
self:defPushMsg{cmd = CoinCmd.Enter_Coin_Room_Response, reader = CoinMessage.EnterCoinResponse, func = handler(self, self.onEnterCoinResponse)} | |||
end | |||
return CoinProtocol |
@@ -0,0 +1,178 @@ | |||
--- 金币场相关PHP请求接口 | |||
local PHPCmd = require("luaScript.Protocol.Coin.CoinPhpCmd") | |||
local CoinData = require("luaScript.Views.Coin.Data.CoinData") | |||
local CoinEvents = require("luaScript.Views.Coin.Constant.CoinEvents") | |||
local CoinDefined = require("luaScript.Views.Coin.Constant.CoinDefined") | |||
local CoinProtocolPhp = class("CoinProtocolPhp") | |||
--- CoinProtocolPhp:ctor | |||
function CoinProtocolPhp:ctor() | |||
self.phpUrl = getGlobalPhpUrl() | |||
CoinData.getInstance():reset() -- 第一次初始化实例 | |||
end | |||
--- CoinProtocolPhp:requestGameServerConfig 请求获取游戏等级配置 | |||
function CoinProtocolPhp:requestGameServerConfig() | |||
local params = { | |||
action = PHPCmd.PHP_GAME_SERVER_CONFIG, | |||
app = getAppId(), | |||
uid = app.user.loginInfo.uid, | |||
gameVer = "" | |||
} | |||
for _, gameId in pairs(GAME_IDS) do | |||
if gameId ~= GAME_IDS.More then | |||
local ver = app.subGameManager:isInstaller(gameId) and app.subGameManager.GameVersions[gameId] or -1 | |||
params.gameVer = params.gameVer .. gameId .. "," .. ver .. "|" | |||
end | |||
end | |||
print("CoinProtocolPhp:requestGameServerConfig() ", table.tostring(params)) | |||
httpPost( | |||
self.phpUrl, | |||
params, | |||
function(status, response) | |||
if status ~= "successed" then | |||
return | |||
end | |||
local data = json.decode(response) | |||
if not (data and data.code == 200 and data.result) then | |||
return | |||
end | |||
local result = data.result | |||
logD("CoinProtocolPhp:requestGameServerConfig response :", table.tostring(result)) | |||
local gameData = {} | |||
gameData.ruleList = {} | |||
local rankImgType = {} | |||
for gameid, content in pairs(result) do | |||
gameData.ruleList[tonumber(gameid)] = content | |||
for gameRank, v in pairsByKeys(content) do | |||
local list = string.sub(gameRank, -1) | |||
local first = string.sub(gameRank, 0, 1) | |||
local gameRule = tonumber(list) | |||
first = tonumber(first) | |||
if gameRule then | |||
local isSame = false | |||
for k, rule in ipairs(gameData.ruleList[tonumber(gameid)]) do | |||
if rule == gameRule then | |||
isSame = true | |||
break | |||
end | |||
end | |||
local isSameImg = false | |||
for k, rule in ipairs(rankImgType) do | |||
if k == first then | |||
isSameImg = true | |||
break | |||
end | |||
end | |||
if not isSame then | |||
if gameData.ruleList[tonumber(gameid)] and gameData.ruleList[tonumber(gameid)][gameRank] then | |||
gameData.ruleList[tonumber(gameid)][gameRank].ruleID = gameRule | |||
end | |||
end | |||
if not isSameImg then | |||
rankImgType[first] = v.icon | |||
end | |||
end | |||
end | |||
end | |||
logD("CoinProtocolPhp:requestGameServerConfig response22 :", table.tostring(gameData)) | |||
CoinData.getInstance():setGameData(gameData) | |||
--下载图片 | |||
logD("需要下载的图片列表:rankImgType:", table.tostring(rankImgType)) | |||
for k, url in pairs(rankImgType) do | |||
local fileName = "coingame" .. k .. ".png" | |||
local fullPath = cc.FileUtils:getInstance():getWritablePath() .. fileName | |||
if not cc.FileSystem:fileExists(fullPath) then | |||
dowloadImageFile(url, fileName, nil) | |||
else | |||
logD(fileName .. "已下载过,无须重复下载!") | |||
end | |||
end | |||
app:dispatchEvent({name = CoinEvents.EVENT_RESPONSE_GAME_SERVER_CONFIG}) | |||
end | |||
) | |||
end | |||
-- 请求金币游戏活动 | |||
function CoinProtocolPhp:requestCoinGameActivity(id) | |||
local appVersion = getAppVersionNum() | |||
local params = | |||
{ | |||
action = PHPCmd.PHP_DAY_FULI, | |||
apkver = appVersion, | |||
uid = app.user.loginInfo.uid, | |||
app = getAppId(), | |||
} | |||
print("CoinProtocolPhp:requestCoinGameActivity() ", table.tostring(params)) | |||
httpPost(self.phpUrl, params, function (status, response) | |||
if status == "successed" then | |||
local data = json.decode(response) | |||
if data and data.result then | |||
print("CoinProtocolPhp:requestCoinGameActivityResponse() ", table.tostring(data.result)) | |||
--数据解析,解析为:每日福利,免费金币两个模块。其中每日福利需要排序显示 | |||
local coinGameActivity = data.result | |||
local shareFreeTimes = 0 | |||
for k,v in pairs(data.result) do | |||
--免费分享的次数 | |||
if v.type == CoinDefined.COIN_GAME_ACTIVITY.TYPE_FREE_COIN then | |||
shareFreeTimes = toNumber(v.need) - toNumber(v.progrss) | |||
end | |||
if v.type == CoinDefined.COIN_GAME_ACTIVITY.TYPE_SHARE_GAME or v.type == CoinDefined.COIN_GAME_ACTIVITY.TYPE_FREE_COIN then | |||
if v.ext then | |||
if v.ext.share_pic ~= "" then | |||
local fileName = getImageNameFromUrl(v.ext.share_pic) | |||
local fullPath = cc.FileUtils:getInstance():getWritablePath()..fileName | |||
if not cc.FileSystem:fileExists(fullPath) then | |||
getImageFromUrlWithTime(v.ext.share_pic, fileName, nil, nil) | |||
else | |||
logD(fileName.."已下载过,无须重复下载!"); | |||
end | |||
v.ext.share_pic = fileName | |||
end | |||
end | |||
end | |||
end | |||
coinGameActivity.shareFreeTimes = shareFreeTimes; | |||
CoinData.getInstance():setGameActivityData(coinGameActivity) | |||
--logD("requestCoinGameActivity:",table.tostring(self.coinGameActivity)) | |||
app:dispatchEvent({name = CoinEvents.EVENT_RESPONSE_GAME_ACTIVITY_CONFIG,response = data.result}); | |||
end | |||
end | |||
end) | |||
end | |||
function CoinProtocolPhp:requestTaskJiangLi(type,callback) | |||
local params = | |||
{ | |||
action = PHPCmd.PHP_DAY_GET_TASK_PRIZE, | |||
token = app.user.loginInfo.token, | |||
uid = app.user.loginInfo.uid, | |||
app = getAppId(), | |||
type = type, | |||
} | |||
print("CoinProtocolPhp:requestTaskJiangLi() ", table.tostring(params)) | |||
httpPost(self.phpUrl, params, function (status, response) | |||
if status == "successed" then | |||
local data = json.decode(response) | |||
if data and data.result then | |||
dump(data,"requestTaskJiangLi") | |||
if callback then | |||
callback(data) | |||
end | |||
end | |||
end | |||
end) | |||
end | |||
return CoinProtocolPhp |
@@ -0,0 +1,936 @@ | |||
--GameAppBase 读的这个 | |||
require("luaScript.Protocol.ProtocolCommon") | |||
require("luaScript.Protocol.Config.ProtocolConfigCmd") | |||
require("luaScript.Protocol.Config.ProtocolConfigMessage") | |||
local ServerConfigs = class("ServerConfigs", require("luaScript.Protocol.Protocol")) | |||
function ServerConfigs:ctor(net) | |||
ServerConfigs.super.ctor(self , net, ModuleId); | |||
-- php 通道相关 | |||
self.phpIndex = 0 | |||
self.phpCallbackList = {}; | |||
self.isGetGameVerList = false | |||
-- 是否已经初始化完成 | |||
self._isInited = false | |||
--是否是改变密码 | |||
self._changePW = false | |||
-- 大厅的配置信息 | |||
self.notice = {}; --{"",""} | |||
self.scroll = ""; -- | |||
self.areano = ""; -- | |||
-- 子游戏的房卡消耗 | |||
self.subGameCosts = {} | |||
-- 子游戏的版本信息 | |||
self.subGameVersions = {} | |||
-- 从gameServer获取的游戏列表 | |||
self.configs = {} | |||
--活动配置 | |||
self.missions = {} | |||
-- 从php获取的游戏列表 | |||
self.subGameList = {} | |||
self.webGameList = table.loadFromLocFile("WebGameList.lua") or {} | |||
self.clientConfig = table.loadFromLocFile("ClientConfig.lua") or { | |||
myHead = "http://cnplayer.ddpenghu.com/client/user/loginpost?wechatid=8&wechatmpid=8", -- 我的装扮 | |||
webgamb = RomSetting.ZhanJiUrl, -- 网页战绩 | |||
} | |||
-- 服务器下发大厅配置 | |||
self:defPushMsg{cmd = ConfigCmd.GAME_COMMAND_SEND_SERVER_CONF, | |||
reader = ServerHallConfigResponse, | |||
func = handler(self , self.onServerHallConfigResponse)}; | |||
-- 服务器下发子游戏配置 | |||
self:defPushMsg{cmd = ConfigCmd.GAME_COMMAND_SEND_GAME_CONF, | |||
reader = ServerGamesConfigResponse, | |||
func = handler(self , self.onServerGamesConfigResponse)}; | |||
-- PHP 通道 | |||
self:defPushMsg{cmd = ConfigCmd.GAME_COMMAND_PHP, | |||
reader = StringPacket, | |||
func = handler(self , self.onPhpMsgResponse)}; | |||
end | |||
-- 初始化 | |||
function ServerConfigs:init() | |||
logD("ServerConfigs:init()") | |||
self.isGetHallConfigSuccess = false | |||
self.isGetGamesConfigSuccess = false | |||
if not self._isInited then | |||
--发送301,返回303 ,304 | |||
self:requestGetServerConfig() | |||
else | |||
self:initSuccessed() | |||
end | |||
end | |||
-- 初始化完成 | |||
function ServerConfigs:initSuccessed() | |||
logD("ServerConfigs:initSuccessed()") | |||
if self._changePW then --是否是修改密码 | |||
logD("ServerConfigs:initSuccessed changePW()") | |||
app.user:dispatchEvent({name = "changePW"}) | |||
self._changePW = false | |||
else | |||
self:dispatchEvent({name = "initSuccessed"}) | |||
end | |||
end | |||
-- 获取子游戏列表 | |||
-- @return {1,2,3,4,5,6,7,8} | |||
function ServerConfigs:getSubGameIds() | |||
local subGameIds = {} | |||
for gameId, v in pairs(self.subGameCosts) do | |||
table.insert(subGameIds, gameId) | |||
end | |||
table.sort(subGameIds) | |||
return subGameIds | |||
end | |||
-- 获取某个子游戏的房卡消耗数据 | |||
function ServerConfigs:getSubGameCostInfo(gameId) | |||
gameId = tonumber(gameId) | |||
if gameId and gameId > 0 then | |||
return self.subGameCosts[gameId] | |||
else | |||
return nil | |||
end | |||
end | |||
-- 获取某个子游戏的版本信息 | |||
function ServerConfigs:getSubGameVersionInfo(gameId) | |||
gameId = tonumber(gameId) | |||
if gameId and gameId > 0 then | |||
return self.subGameVersions[gameId] | |||
else | |||
return nil | |||
end | |||
end | |||
-- 获取某个子游戏的服务器版本 | |||
function ServerConfigs:getSubGameVersionNum(gameId) | |||
local versionInfo = self:getSubGameVersionInfo(gameId) | |||
if versionInfo and versionInfo.ver then | |||
return tonumber(versionInfo.ver) | |||
else | |||
return -1 | |||
end | |||
end | |||
-- 是否正在改变密码的情况 | |||
function ServerConfigs:getChangePWState() | |||
return self._changePW | |||
end | |||
function ServerConfigs:setChangePWState(bChangePW) | |||
self._changePW = bChangePW | |||
end | |||
--------------------------------------------------------------------------- | |||
-------------------------------- PHP 通道 -------------------------------- | |||
--------------------------------------------------------------------------- | |||
-- ttInfo : 传送给PHP的数据 | |||
-- callback : 处理后的回调 | |||
function ServerConfigs:sendPhpMsg(ttInfo, callback) | |||
if not ttInfo or type(ttInfo) ~= "table" then | |||
return | |||
end | |||
-- 索引++ | |||
self.phpIndex = self.phpIndex + 1; | |||
-- 记录回调索引 | |||
local callbackKey = self.phpIndex .. "_" .. (ttInfo.pSSq or "0") | |||
self.phpCallbackList[callbackKey] = callback | |||
-- 改变发往服务器的索引 | |||
ttInfo.pSSq = callbackKey | |||
local strContent = json.encode(ttInfo) | |||
-- 发送消息到服务器 | |||
local request = StringPacket:new() | |||
request.stringValue = strContent; | |||
logD("ServerConfigs:sendPhpMsg() request = " .. table.tostring(request)) | |||
self:sendResponse{cmd = ConfigCmd.GAME_COMMAND_PHP , sender = request}; | |||
end | |||
function ServerConfigs:onPhpMsgResponse(status, response) | |||
logD("ServerConfigs:onPhpMsgResponse()", tostring(status), table.tostring(response)) | |||
if status ~= 0 then | |||
return | |||
end | |||
local ttResult = json.decode(response.stringValue) | |||
if not ttResult then | |||
return | |||
end | |||
local index = tostring(ttResult.pSSq) | |||
if not index then | |||
return | |||
end | |||
if not self.phpCallbackList[index] then | |||
return | |||
end | |||
self.phpCallbackList[index](0, ttResult); | |||
self.phpCallbackList[index] = nil; | |||
end | |||
--------------------------------------------------------------------------- | |||
-------------------------------- 配置相关 -------------------------------- | |||
--------------------------------------------------------------------------- | |||
-- 获取配置信息 | |||
function ServerConfigs:requestGetServerConfig() | |||
local request = ServerConfigRequest:new() | |||
request.appId = getAppId() | |||
log("ServerConfigs:requestGetServerConfig() request = ", table.tostring(request)) | |||
self:sendResponse{cmd = ConfigCmd.GAME_COMMAND_GET_SERVER_CONF , sender = request}; | |||
end | |||
-- 服务器下发大厅配置 | |||
function ServerConfigs:onServerHallConfigResponse(status, response) | |||
logD("ServerConfigs:ServerHallConfigResponse()", tostring(status), table.tostring(response)) | |||
local ttResult = json.decode(response.strContent) | |||
-- 公告信息 | |||
self.notice = {} | |||
local notice = tostring(ttResult.notice) or "" | |||
if notice ~= "" then | |||
local arr = string.split(notice, "\n") | |||
for k,v in pairs(arr) do | |||
table.insert(self.notice, v) | |||
end | |||
end | |||
-- 滚动公告 | |||
self.scroll = tostring(ttResult.scroll) or "" | |||
-- 游戏ID | |||
self.gameId = tonumber(ttResult.gameId) or 0 | |||
-- 区域信息 | |||
self.areano = tonumber(ttResult.areano) or 0 | |||
-- 记录获取大厅配置成功 | |||
self.isGetHallConfigSuccess = true | |||
self:onGetServerConfigSuccessed(); | |||
end | |||
-- 服务器下发子游戏配置 | |||
function ServerConfigs:onServerGamesConfigResponse(status, response) | |||
log("ServerConfigs:onServerGamesConfigResponse()", tostring(status), table.tostring(response)) | |||
self.configs = {} | |||
self.subGameCosts = {} | |||
for _, value in pairs(response.gameServerConfigList) do | |||
local costConfig = json.decode(value) | |||
if costConfig and type(costConfig) == "table" and costConfig.gameid then | |||
--[[ | |||
-- 基本属性 | |||
costConfig = | |||
{ | |||
gameid = 18, --游戏ID | |||
isFree = 1, --免费标签 | |||
gameRound = "4,6,8", --支持的局数 | |||
requireCards = "0,0,0", --房主支付消耗的房卡数量 | |||
AArequireCards = "0,0,0", --AA支付消耗的房卡数量 | |||
} | |||
--]] | |||
--连打房间解散时间,黄十八用 | |||
if costConfig.contiTimer then | |||
app.user.contiTimer = costConfig.contiTimer | |||
end | |||
self.configs[tonumber(costConfig.gameid)] = costConfig; | |||
--[[ | |||
-- 转换成 | |||
costInfo = | |||
{ | |||
{round = 4, cost = 0, aaCost = 0}, | |||
{round = 4, cost = 0, aaCost = 0}, | |||
{round = 4, cost = 0, aaCost = 0}, | |||
} | |||
--]] | |||
local costInfo = {} | |||
local Rounds = {} | |||
local Costs = {} | |||
local AACosts = {} | |||
if costConfig.gameRound then | |||
Rounds = string.split(costConfig.gameRound, ",") | |||
end | |||
if costConfig.requireCards then | |||
Costs = string.split(costConfig.requireCards, ",") | |||
end | |||
if costConfig.AArequireCards then | |||
AACosts = string.split(costConfig.AArequireCards, ",") | |||
end | |||
for idx,round in pairs(Rounds) do | |||
if tonumber(round) == 24 and tonumber(costConfig.gameid) == 2 then | |||
else | |||
table.insert(costInfo, {round = tonumber(round), cost = tonumber(Costs[idx]), aaCost = tonumber(AACosts[idx])}) | |||
end | |||
end | |||
self.subGameCosts[tonumber(costConfig.gameid)] = costInfo | |||
end | |||
end | |||
self.isGetGamesConfigSuccess = true; | |||
self:onGetServerConfigSuccessed(); | |||
end | |||
-- 获取配置完成后的处理 | |||
function ServerConfigs:onGetServerConfigSuccessed() | |||
if self.isGetHallConfigSuccess and self.isGetGamesConfigSuccess then | |||
-- 初始化子游戏配置 | |||
if app.subGameConfigManager then | |||
app.subGameConfigManager:init() | |||
end | |||
-- 初始化子游戏版本信息 | |||
self:initSubGameVersions(); | |||
-- 初始化地区对应的游戏列表 | |||
self:initSubGameList(); | |||
self:initSuccessed() | |||
end | |||
end | |||
--------------------------------------------------------------------------- | |||
-------------------------------- 子游戏版本 ------------------------------- | |||
--------------------------------------------------------------------------- | |||
-- 初始化子游戏版本信息 | |||
function ServerConfigs:initSubGameVersions() | |||
-- 首先从本地缓存中加载上一次的配置 | |||
self:loadSubGameVersionsFromFile() | |||
-- 然后从服务器拉取最新的数据 | |||
self:requestGetSubGameVersions() | |||
end | |||
function ServerConfigs:loadSubGameVersionsFromFile() | |||
self.subGameVersions = table.loadFromLocFile("SubGameVersions.lua") or {} | |||
logD("ServerConfigs:loadSubGameVersionsFromFile()", table.tostring(self.subGameVersions)) | |||
end | |||
function ServerConfigs:saveSubGameVersionsToFile() | |||
logD("ServerConfigs:saveSubGameVersionsToFile()", table.tostring(self.subGameVersions)) | |||
table.saveToLocFile(self.subGameVersions, "SubGameVersions.lua") | |||
end | |||
-- 获取子游戏版本信息 | |||
function ServerConfigs:requestGetSubGameVersions() | |||
local params = | |||
{ | |||
action = "system.games", | |||
app = getAppId(), | |||
uid = loadUserId(), | |||
apkver = "",-- 获取子游戏版本号时不再依赖APK的版本号 - zzb,20190715 | |||
installGameVer = "", | |||
isNew =1, | |||
} | |||
for gameId,v in pairs(self.subGameCosts) do | |||
local version = app.subGameManager:getSubGameVersionNum(gameId) | |||
params.installGameVer = params.installGameVer..gameId..","..version.."|" | |||
end | |||
--基础包 | |||
local baseIds={1001,1002,1003} | |||
for k,gameId in pairs(baseIds) do | |||
local version = app.subGameManager:getSubGameVersionNum(gameId) | |||
params.installGameVer = params.installGameVer..gameId..","..version.."|" | |||
end | |||
logD("ServerConfigs:requestGetSubGameVersions() ", table.tostring(params)); | |||
self:sendPhpMsg(params, handler(self, self.onGetSubGameVersionsResponse)) | |||
end | |||
function ServerConfigs:onGetSubGameVersionsResponse(status, ttResult) | |||
logD("ServerConfigs:onGetSubGameVersionsResponse() " .. table.tostring(ttResult)) | |||
self.getsubGameList = true | |||
if ttResult and tonumber(ttResult.code) == 200 and ttResult.result and type(ttResult.result) == "table" then | |||
if ttResult.result.new and type(ttResult.result.new) == "table" then | |||
for gameId,v in pairs(ttResult.result.new) do | |||
local gameId = tonumber(gameId) | |||
self.subGameVersions[gameId] = v | |||
end | |||
end | |||
-- 将最新的数据写入到本地缓存 | |||
self:saveSubGameVersionsToFile(); | |||
end | |||
end | |||
--------------------------------------------------------------------------- | |||
-------------------------------- 子游戏列表 ------------------------------- | |||
--------------------------------------------------------------------------- | |||
-- 获取指定子游戏的配置信息 | |||
-- 可能返回 nil | |||
function ServerConfigs:getSubGameConfig(gameId) | |||
if not gameId then | |||
return nil | |||
end | |||
return self.subGameList[gameId] | |||
end | |||
-- 获取指定web子游戏的配置信息 | |||
-- 可能返回 nil | |||
function ServerConfigs:getWebGameConfig(gameId) | |||
for i,v in pairs(self.webGameList) do | |||
if v.gameId == gameId then | |||
return v | |||
end | |||
end | |||
return nil | |||
end | |||
function ServerConfigs:requestClientConfig(callback) | |||
logD("ServerConfigs:requestClientConfig()") | |||
local params = | |||
{ | |||
action = "system.clicfg", | |||
app = getAppId(), | |||
uid = loadUserId(), | |||
} | |||
logD("ServerConfigs:requestClientConfig() ", table.tostring(params)); | |||
app.waitDialogManager:showWaitNetworkDialog("请求配置...") | |||
self:sendPhpMsg(params, function(status,response) | |||
app.waitDialogManager:closeWaitNetworkDialog() | |||
logD("ServerConfigs:requestClientConfigResponse() ", table.tostring(response)); | |||
if tonumber(response.code)==200 then | |||
if response.result and table.nums(response.result)>0 then | |||
self.clientConfig = response.result | |||
table.saveToLocFile(self.clientConfig, "ClientConfig.lua") | |||
app.config.Setting.appDownloadUrl = self.clientConfig.download | |||
math.randomseed(tostring(os.time()):reverse():sub(1, 6)); | |||
local wx = response.result.wx or {}; | |||
if table.nums(wx) > 0 then | |||
local idx = math.random(table.nums(wx)) | |||
if wx[idx] then | |||
app.plugin:initWxShare(wx[idx].appid, wx[idx].secret); | |||
else | |||
app.plugin:initWxShare(wx.appid, wx.secret); | |||
end | |||
else | |||
if app.plugin and wx.appid and wx.secret then | |||
app.plugin:initWxShare(wx.appid, wx.secret); | |||
end | |||
end | |||
end | |||
end | |||
if callback then callback() end | |||
app:dispatchEvent({name = "onRequestClientConfig"}) | |||
end) | |||
end | |||
function ServerConfigs:requestWebGameUrl(gameId,callback) | |||
local function getOrientation (url) | |||
local orientation = 1; | |||
local index = string.find(url,"?") | |||
if index then | |||
local params=string.sub(url,index+1,string.len(url)) | |||
local tmp = string.split(params,"&"); | |||
local args = {}; | |||
for k, v in pairs(tmp) do | |||
local arr = string.split(v, "="); | |||
if arr[1] == "orientation" then | |||
orientation = arr[2] or 1; | |||
break; | |||
end | |||
end | |||
end | |||
return orientation; | |||
end | |||
local params = | |||
{ | |||
action = "platform.geturl", | |||
app = getAppId(), | |||
uid = loadUserId(), | |||
tinyid = gameId, | |||
} | |||
logD("ProtocolSubGame:requestWebGameList() ", table.tostring(params)); | |||
self:sendPhpMsg(params,function (status,response) | |||
dump(response) | |||
if tonumber(response.code)==200 then | |||
local orientation = getOrientation(response.result); | |||
if callback then callback(response.result, tonumber(orientation)) end | |||
else | |||
if callback then callback() end | |||
end | |||
end) | |||
end | |||
function ServerConfigs:getGameGroupConfig(gameId, regionCode) | |||
regionCode = regionCode or 0 | |||
local subGameList = self.regionGameList[regionCode] or self.subGameList | |||
if subGameList[gameId] then | |||
local strGameConfig = subGameList[gameId].gameRule | |||
if strGameConfig and strGameConfig~="" then | |||
local gameConfig = json.decode(strGameConfig) | |||
if gameConfig and gameConfig.group and gameConfig.group.games then | |||
return gameConfig.group | |||
end | |||
end | |||
end | |||
return nil | |||
end | |||
function ServerConfigs:getWebGameGroupConfig(gameId) | |||
for i,v in pairs(self.webGameList) do | |||
if v.gameId == gameId then | |||
local strGameConfig = v.gamecfg | |||
if strGameConfig and strGameConfig~="" then | |||
local gameConfig = json.decode(strGameConfig) | |||
if gameConfig and gameConfig.group then | |||
return gameConfig.group | |||
end | |||
end | |||
end | |||
end | |||
return nil | |||
end | |||
--- | |||
-- 子游戏是否在合集里面 | |||
-- @return boolean | |||
-- | |||
function ServerConfigs:isWebGameInGroup (gameId) | |||
local isExist = false | |||
for i,v in pairs(self.webGameList) do | |||
local groupConfig = self:getWebGameGroupConfig(v.gameId) or {} | |||
local games = groupConfig.games or {} | |||
for _, id in ipairs(games) do | |||
if tonumber(id) == tonumber(gameId) then | |||
isExist = true | |||
break | |||
end | |||
end | |||
if isExist then | |||
break | |||
end | |||
end | |||
return isExist | |||
end | |||
function ServerConfigs:isNewGame(gameId) | |||
if self.subGameList[gameId] then | |||
local strGameConfig = self.subGameList[gameId].gameRule | |||
if strGameConfig and strGameConfig~="" then | |||
local gameConfig = json.decode(strGameConfig) | |||
if gameConfig and gameConfig.isNew then | |||
return gameConfig.isNew | |||
end | |||
end | |||
end | |||
return false | |||
end | |||
--- | |||
-- 获取子游戏列表 | |||
-- @return | |||
-- | |||
function ServerConfigs:getSubGameList() | |||
return self.subGameList | |||
end | |||
--- | |||
-- 获取子游戏列表(没有子游戏具体信息) | |||
-- @return | |||
-- | |||
function ServerConfigs:getGameList(regionCode) | |||
regionCode = regionCode or 0 | |||
local gameList = {} | |||
local baseIds={ | |||
[1001]=true, | |||
[1002]=true, | |||
[1003]=true | |||
} | |||
if isIOSReviewVersion() then | |||
-- 添加更多游戏的显示 | |||
local gameInfo = | |||
{ | |||
gameId = 0; | |||
gameName = "更多游戏"; | |||
sortIndex = 9999; | |||
show = true; | |||
visible = true; | |||
} | |||
self.subGameList[gameInfo.gameId] = gameInfo | |||
end | |||
local subGameList = self.regionGameList[regionCode] or self.subGameList | |||
local tt = {} | |||
for k,v in pairs(subGameList) do | |||
if v.visible and v.showInHall == 1 then | |||
if v.other_name and v.other_name ~= "" then | |||
if not tt[v.other_name] then | |||
tt[v.other_name] = {} | |||
end | |||
table.insert(tt[v.other_name],{gameId = v.gameId, sort = v.sortIndex ,gameType = "sub"}) | |||
elseif v.gameId and not baseIds[v.gameId] then | |||
table.insert(gameList,{gameId = v.gameId, sort = v.sortIndex ,gameType = "sub"}) | |||
end | |||
end | |||
end | |||
for k,v in pairs(tt) do | |||
--求最小排序 | |||
table.sort(v, function (a,b) | |||
return a.sort<b.sort | |||
end) | |||
table.insert(gameList,{data = v,sort = v[1].sort,gameType = "sub",gameId = v[1].gameId}) | |||
end | |||
--如果是苹果审核版则不需要小游戏 | |||
if not isIOSReviewVersion() then | |||
local ttWebGame = {} | |||
for k,v in pairs(self.webGameList) do | |||
if v.other_name and v.other_name ~= "" then | |||
if not tt[v.other_name] then | |||
tt[v.other_name] = {} | |||
end | |||
table.insert(tt[v.other_name],{gameId = v.gameId, sort = v.sortIndex ,gameType = "web"}) | |||
else | |||
table.insert(gameList,{gameId = v.gameId, icon = v.icon, sort = v.sort ,gameType = "web"}) | |||
end | |||
end | |||
for k,v in pairs(ttWebGame) do | |||
table.insert(gameList,{data = v,sort = v[1].sort,gameType = "web",gameId = v[1].gameId}) | |||
end | |||
end | |||
table.sort(gameList, function (a,b) | |||
return a.sort<b.sort | |||
end) | |||
dump(gameList,"--hall gamelist--") | |||
return gameList | |||
end | |||
--是否对当前用户打开webGame | |||
function ServerConfigs:isOpenWebGame(gameId) | |||
local isOpen = false | |||
local gamecfg = nil | |||
for k,v in pairs(self.webGameList) do | |||
if v.gameId==gameId then | |||
gamecfg = v.gamecfg | |||
break | |||
end | |||
end | |||
-- local gamecfg = webGame.gamecfg --添加userid 字段判断白名单测试 | |||
if gamecfg and gamecfg~="" then | |||
local cfg = json.decode(gamecfg) | |||
if cfg and cfg.userId then | |||
local users = string.split(cfg.userId,",") | |||
for k,v in pairs(users) do | |||
if tonumber(v) == tonumber(app.user.loginInfo.uid) then | |||
isOpen = true | |||
end | |||
end | |||
else | |||
isOpen = true | |||
end | |||
else | |||
isOpen = true | |||
end | |||
return isOpen | |||
end | |||
function ServerConfigs:isNewWebGame(gameId) | |||
local isNew = false | |||
local gamecfg = nil | |||
for k,v in pairs(self.webGameList) do | |||
if v.gameId==gameId then | |||
gamecfg = v.gamecfg | |||
break | |||
end | |||
end | |||
-- local gamecfg = webGame.gamecfg --添加userid 字段判断白名单测试 | |||
if gamecfg and gamecfg~="" then | |||
local cfg = json.decode(gamecfg) | |||
if cfg and cfg.isNew then | |||
isNew = cfg.isNew | |||
end | |||
end | |||
return isNew | |||
end | |||
--获取活动数据列表(新接口) | |||
function ServerConfigs:requestMissionList() | |||
local params = | |||
{ | |||
action= "missions.lists", | |||
uid = app.user.loginInfo.uid, | |||
app = getAppId(), | |||
} | |||
logD("ServerConfigs:requestMissionList()", table.tostring(params)) | |||
self:sendPhpMsg(params, function(status,response) | |||
-- if status ~= "successed" then | |||
-- logE("活动数据拉取失败") | |||
-- return | |||
-- end | |||
-- local data = json.decode(response) | |||
logD("ServerConfigs:requestMissionList()", table.tostring(response)) | |||
if tonumber(response.code)~=200 then | |||
logE("活动数据错误") | |||
return | |||
end | |||
-- "code":200, | |||
-- "error":"", | |||
-- "result":{ | |||
-- { | |||
-- "id" : 1, //任务ID | |||
-- "type": 1, //任务类型 4展示任务 | |||
-- "name":"活动名称", //任务名称 | |||
-- "desc":"" //任务描述 | |||
-- "ishot": 1, //是否最热 | |||
-- "sort":1, //排序 | |||
-- "ext":'', //扩展信息 | |||
-- "pic":'', //图片 | |||
-- "catalog":1, //活动分类 1 游戏公告 2 精彩活动 | |||
-- } | |||
-- } | |||
self.missions = response.result or {} | |||
app:dispatchEvent({name = "onGetActivityInfoResponse"}) | |||
end) | |||
end | |||
function ServerConfigs:getMissionListByType(catalog) | |||
local missions = {} | |||
local stickyIndex = 1 --置顶的index | |||
for k,v in pairs(self.missions) do | |||
if v.catalog == catalog then | |||
table.insert(missions,v) | |||
end | |||
--if v.sticky==1 then --置顶 | |||
-- stickyIndex = #missions | |||
--end | |||
end | |||
table.sort(missions,function(a,b) | |||
return a.sort<b.sort | |||
end) | |||
for k,v in pairs(missions) do | |||
if v.sticky==1 then --置顶 | |||
stickyIndex = k | |||
end | |||
end | |||
return missions,stickyIndex | |||
end | |||
--获取置顶类型 | |||
function ServerConfigs:getStickyType() | |||
local catalog = 1 --置顶的类型 | |||
for k,v in pairs(self.missions) do | |||
if v.sticky==1 then --置顶 | |||
catalog = v.catalog | |||
end | |||
end | |||
return catalog | |||
end | |||
function ServerConfigs:popConfig() | |||
self:initPopConfig() | |||
if self.popConfigs and #self.popConfigs>0 then | |||
local config = self.popConfigs[1] | |||
table.remove(self.popConfigs,1) | |||
return config | |||
end | |||
return nil | |||
end | |||
function ServerConfigs:initPopConfig() | |||
if self.popConfigs then | |||
return | |||
end | |||
--弹出配置 | |||
if cc.Application:getInstance():getTargetPlatform() == 0 then | |||
-- self.popConfigs = {"luaScript.Views.Main.HongBaoKa.HongBaoKaView", "luaScript.Views.Activity.ActivityMainView"} | |||
self.popConfigs = {} | |||
else | |||
local popWindows = PhpSetting["pop_window"] or {} | |||
table.sort(popWindows, function (a, b) | |||
return a.index < b.index | |||
end) | |||
local configs = {} | |||
for _, v in ipairs(popWindows or {}) do | |||
if v then | |||
table.insert(configs, v.view) | |||
end | |||
end | |||
self.popConfigs = configs; | |||
end | |||
end | |||
-------------------------------------------------------------------------------------------------------------------------------- | |||
-------------------------------------------------------------------------------------------------------------------------------- | |||
-------------------------------------------------------------------------------------------------------------------------------- | |||
-------------------------------------------------------------------------------------------------------------------------------- | |||
function ServerConfigs:initSubGameList() | |||
-- 所有的游戏 | |||
self.subGameList = {} | |||
-- 各区域对应的游戏列表 | |||
self.regionGameList = {} | |||
-- 先充本地缓存中读取数据 | |||
self:loadSubGameListFromFile(); | |||
-- 再从服务器获取最新的数据 | |||
self:requestGameList(0, function () | |||
-- 再根据当前选择地区,再拉取对应地区的游戏列表 | |||
local regionCode = cc.UserDefault:getInstance():getIntegerForKey("address_code_" .. app.config.RomSetting.Platform) | |||
self:requestGameList(regionCode) | |||
end) | |||
end | |||
function ServerConfigs:saveSubGameListToFile() | |||
logD("ServerConfigs:saveSubGameListToFile()", table.tostring(self.subGameList)) | |||
table.saveToLocFile(self.subGameList, "SubGameList.lua") | |||
end | |||
function ServerConfigs:loadSubGameListFromFile() | |||
self.subGameList = table.loadFromLocFile("SubGameList.lua") or {} | |||
logD("ServerConfigs:loadSubGameListFromFile()", table.tostring(self.subGameList)) | |||
end | |||
function ServerConfigs:requestGameList(regionCode, isFirstRequest, callback) | |||
-- 保存所有地区的游戏列表数据 | |||
self.regionGameList = self.regionGameList or {} | |||
-- 默认获取全国的数据 | |||
regionCode = regionCode or 0 | |||
if self.regionGameList[regionCode] then | |||
-- 如果已经请求过该地区的数据,则不再请求游戏列表 | |||
self:dispatchEvent({name = "getSubGameListSuccessed"}) | |||
app.waitDialogManager:closeWaitNetworkDialog() | |||
return | |||
end | |||
local params = | |||
{ | |||
action = "system.uniongameinfo", | |||
app = getAppId(), | |||
uid = loadUserId(), | |||
region = regionCode, | |||
} | |||
logD("ServerConfigs:requestGameList(), params = ", table.tostring(params)) | |||
self:sendPhpMsg(params, function(status, response) | |||
logD("ServerConfigs:requestGameList(), response = ", table.tostring(response)) | |||
app.waitDialogManager:closeWaitNetworkDialog() | |||
if tonumber(response.code) == 200 then | |||
local subGameList = {} | |||
if response.result.game then | |||
for k,v in pairs(response.result.game) do | |||
local gameId = tonumber(k) | |||
local gamecfg = v.gamecfg | |||
local gamecfgData = json.decode(gamecfg) | |||
local gameInfo = {} | |||
gameInfo.gameId = gameId | |||
gameInfo.gameName = tostring(v.name) | |||
gameInfo.gameIcon = tostring(v.icon) | |||
gameInfo.gameRule = tostring(v.gamecfg) | |||
gameInfo.sortIndex = tonumber(v.sort) | |||
gameInfo.other_name = tostring(v.other_name) | |||
gameInfo.show = true | |||
--游戏列表的显示逻辑用visible,创建房间的逻辑用show | |||
if gamecfgData then | |||
if gamecfgData.group and gamecfgData.group.show == "0" then | |||
gameInfo.visible = false | |||
else | |||
gameInfo.visible = true | |||
end | |||
if not gamecfgData.showInHall then | |||
gameInfo.showInHall = 1 | |||
else | |||
gameInfo.showInHall = tonumber(gamecfgData.showInHall) | |||
end | |||
else | |||
gameInfo.visible = true | |||
gameInfo.showInHall = 1 | |||
end | |||
subGameList[gameId] = gameInfo | |||
end | |||
if regionCode == 0 then | |||
self.subGameList = subGameList; | |||
self:saveSubGameListToFile() | |||
end | |||
end | |||
-- 记录已经拉取过的地区游戏列表 | |||
self.regionGameList[regionCode] = subGameList | |||
self.webGameList = {} | |||
if response.result.tiny then | |||
for gameId,v in pairs(response.result.tiny) do | |||
v.gameId = tonumber(gameId) | |||
local gamecfgData = json.decode(v.gamecfg) | |||
if gamecfgData then | |||
local uids = gamecfgData.uids | |||
local uid = app.user.loginInfo.uid | |||
if uids then | |||
for _, vv in pairs(uids) do | |||
if tonumber(vv) == uid then | |||
table.insert(self.webGameList, v) | |||
break | |||
end | |||
end | |||
else | |||
table.insert(self.webGameList, v) | |||
end | |||
else | |||
table.insert(self.webGameList, v) | |||
end | |||
end | |||
table.saveToLocFile(self.webGameList, "WebGameList.lua") | |||
end | |||
self:dispatchEvent({name = "getSubGameListSuccessed"}) | |||
end | |||
end) | |||
end | |||
return ServerConfigs |
@@ -0,0 +1,35 @@ | |||
ConfigCmd = | |||
{ | |||
--[[/** | |||
* 客户端请求获取配置信息 | |||
* <pre> | |||
* 请求: {@code ServerConfigRequest} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_GET_SERVER_CONF = 0x0301, | |||
--[[/** | |||
* server返回大厅的配置信息 | |||
* <pre> | |||
* 推送: {@code ServerHallConfigResponse} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_SEND_SERVER_CONF = 0x0302, | |||
--[[/** | |||
* server返回子游戏的配置信息 | |||
* <pre> | |||
* 推送: {@code ServerGamesConfigResponse} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_SEND_GAME_CONF = 0x0303, | |||
--[[/** | |||
* 客户端和PHP之间交互使用的TCP通道 | |||
* <pre> | |||
* 请求: {@code StringPacket} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_PHP = 0x0401, | |||
} | |||
return ConfigCmd; |
@@ -0,0 +1,19 @@ | |||
-- 登陆之前配置请求 | |||
ServerConfigRequest = defClass("ServerConfigRequest" | |||
-- gameId | |||
,defVar("appId", VT_String, "") | |||
) | |||
-- 服务器返回配置 | |||
ServerHallConfigResponse = defClass("ServerHallConfigResponse" | |||
--json格式的信息 | |||
, defVar("strContent", VT_String, "") | |||
) | |||
-- 多游戏配置数据 | |||
ServerGamesConfigResponse = defClass("ServerGamesConfigResponse" | |||
-- 各个游戏的配置信息,json格式, | |||
, defVar("gameServerConfigList", VT_Vector(VT_String), {}) | |||
) |
@@ -0,0 +1,284 @@ | |||
-- 用来记录比赛流程,适用用比赛重播 | |||
-- 用单例模式会好点,直接用GameRecordController.getInstance() 而不要用 new | |||
-- round, 轮,site,局,userInfo中保留每轮合计数据,每轮数据可获得每轮的详细数据文件名,包含此轮每局的数据 | |||
GameRecordController = class("GameRecordController") | |||
GameRecordController.k_max_record_num = 10 | |||
-- 深度封装,解析json | |||
local function encodeJson(tables) | |||
if type(tables) ~= "table" then return tables end | |||
local tt = {} | |||
for k, v in pairs(tables) do | |||
if type(v) == "table" then | |||
tt[k] = encodeJson(v) | |||
else | |||
tt[k] = v | |||
end | |||
-- 数字开始key调用json.encode会有问题,所以加入了一个前缀 | |||
if type(k) == "number" then | |||
tt["_ddnum_"..k] = tt[k] | |||
tt[k] = nil | |||
end | |||
end | |||
return json.encode(tt) | |||
end | |||
local function decodeJson(string) | |||
if type(string) ~= "string" then return string end | |||
local map = json.decode(string) | |||
local tt = {} | |||
if type(map) == "table" then | |||
for k, v in pairs(map) do | |||
local value = v | |||
if string.find(v, "{") then | |||
value = decodeJson(v) | |||
end | |||
if string.find(k, "_ddnum_") then | |||
local str = string.gsub(k, "_ddnum_", "") | |||
tt[tonumber(str)] = value | |||
else | |||
if value == {} then | |||
tt[k] = v | |||
else | |||
tt[k] = value | |||
end | |||
end | |||
end | |||
end | |||
return tt | |||
end | |||
function GameRecordController.getInstance() | |||
if not GameRecordController.m_instance then | |||
GameRecordController.m_instance = GameRecordController:new() | |||
end | |||
return GameRecordController.m_instance | |||
end | |||
-- 开启记录模式 | |||
function GameRecordController:ctor() | |||
end | |||
-- 中途加入的以加入房间的时间为准 | |||
function GameRecordController:setMyUserId(uid, userInfo) | |||
-- log("GameRecordController:setMyUserId", uid, table.tostring(userInfo)) | |||
self.m_myUserId = uid | |||
self.m_userNameMap = self.m_userNameMap or {} | |||
self.m_userNameMap[uid] = userInfo.nickname | |||
end | |||
function GameRecordController:setBeginTime() | |||
saveUserInfo("GameRoundLastBeginTime", os.time()) | |||
end | |||
function GameRecordController:addOtherUserId(uid, userInfo) | |||
-- log("GameRecordController:addOtherUserId", uid, table.tostring(userInfo)) | |||
self.m_otherUserIds = self.m_otherUserIds or {} | |||
if uid and uid ~= self.m_myUserId then | |||
local haveThisUid = false | |||
for _, id in pairs(self.m_otherUserIds) do | |||
if id == uid then | |||
haveThisUid = true | |||
end | |||
end | |||
if not haveThisUid then | |||
table.insert(self.m_otherUserIds, uid) | |||
end | |||
self.m_userNameMap = self.m_userNameMap or {} | |||
self.m_userNameMap[uid] = userInfo.nickname | |||
end | |||
end | |||
-- 获取游戏开局时间 | |||
function GameRecordController:getBeginTime() | |||
local beginTime = loadUserInfo("GameRoundLastBeginTime") | |||
return beginTime | |||
end | |||
-- 获取当前房间号 | |||
function GameRecordController:getTotalTableId() | |||
return self.m_totalTableId | |||
end | |||
-- 每局的开始时间 | |||
function GameRecordController:setTotalTime(time) | |||
-- log("GameRecordController:setTotalTime", time) | |||
self.m_totalTime = time | |||
end | |||
-- 记录当前房间号,只有当玩家进入房间成功以及重连回来时才会记录房间号 | |||
function GameRecordController:setTotalTableId(totalTableId) | |||
-- log("GameRecordController:setTotalTableId", totalTableId) | |||
self.m_totalTableId = totalTableId | |||
end | |||
-- 记录当前局数和总局数 | |||
function GameRecordController:setGameNum(gameStartCount, totalGameNum) | |||
-- log("GameRecordController:setGameNum", gameStartCount, totalGameNum) | |||
self.m_gameStartCount = gameStartCount | |||
self.m_totalGameNum = totalGameNum | |||
if self.m_gameStartCount == 1 then | |||
if self.m_totalTime then | |||
saveUserInfo("GameRoundLastBeginTime", self.m_totalTime) | |||
end | |||
end | |||
end | |||
function GameRecordController:setSumGameNum(sumGameNum) | |||
-- log("GameRecordController:setSumTableId", sumGameNum) | |||
self.m_sumGameNum = sumGameNum | |||
end | |||
function GameRecordController:setGameOverData(response) | |||
log("GameRecordController:setGameOverData", table.tostring(response)) | |||
-- 记录我的当前积分,保持此轮总数据 | |||
if type(response) ~= "table" then return end | |||
local userTurnMoneyMaps = {} | |||
for k,v in pairs(response.userCountList) do | |||
if v.nUserId == self.m_myUserId then | |||
self.m_totalMoney = v.nTotalMoney | |||
end | |||
userTurnMoneyMaps[v.nUserId] = v.nTurnMoney | |||
end | |||
self:writeRoundData() | |||
local data = { | |||
userTurnMoneyMaps = encodeJson(userTurnMoneyMaps), | |||
gameStartCount = self.m_gameStartCount, | |||
totalTime = self.m_totalTime, | |||
} | |||
self:writeSiteData(data) | |||
end | |||
-- 通過房間號和當前局數讀取數據 | |||
function GameRecordController:readSiteData(beginTime, tableId) | |||
local totalRoundFileName = "totalRoundFileName"..beginTime..tableId | |||
local GameRecordSiteNum = loadUserXml("GameRecordSiteSumNum", totalRoundFileName) | |||
-- log("xiabo__s", GameRecordSiteNum) | |||
-- log("xiabo__s", beginTime) | |||
-- log("xiabo__s", tableId) | |||
GameRecordSiteDatas = {} | |||
if GameRecordSiteNum then | |||
GameRecordSiteNum = tonumber(GameRecordSiteNum) | |||
if GameRecordSiteNum and GameRecordSiteNum >= 1 then | |||
for i = 1, GameRecordSiteNum do | |||
local totalSiteData = loadUserXml("GameRecordSiteData"..i, totalRoundFileName) | |||
if type(totalSiteData) == "string" then | |||
-- log("xiabo", totalSiteData) | |||
totalSiteData = decodeJson(totalSiteData) | |||
end | |||
if type(totalSiteData) == "table" and next(totalSiteData) then | |||
-- log("xiabo", table.tostring(totalSiteData)) | |||
-- log("xiabo", totalSiteData.userTurnMoneyMaps) | |||
if type(totalSiteData.userTurnMoneyMaps) == "string" then | |||
totalSiteData.userTurnMoneyMaps = decodeJson(totalSiteData.userTurnMoneyMaps) | |||
end | |||
-- log("xiabo", table.tostring( totalSiteData.userTurnMoneyMaps)) | |||
table.insert(GameRecordSiteDatas, totalSiteData) | |||
end | |||
end | |||
end | |||
end | |||
-- log("GameRecordController:readSiteData data", table.tostring(GameRecordSiteDatas)) | |||
return GameRecordSiteDatas | |||
end | |||
function GameRecordController:writeSiteData(data) | |||
log("GameRecordController:writeSiteData data", table.tostring(data)) | |||
-- 先获取这一轮对应的文件名 | |||
local beginTime = loadUserInfo("GameRoundLastBeginTime") | |||
local totalRoundFileName = "totalRoundFileName"..beginTime..self.m_totalTableId | |||
-- log("GameRecordController", totalRoundFileName) | |||
local GameRecordSiteNum = loadUserXml("GameRecordSiteSumNum", totalRoundFileName) | |||
-- log("GameRecordController", GameRecordSiteNum) | |||
GameRecordSiteNum = tonumber(GameRecordSiteNum or "") or 0 | |||
local num = math.min(GameRecordSiteNum + 1, data.gameStartCount) | |||
saveUserXml("GameRecordSiteSumNum", num, totalRoundFileName) | |||
saveUserXml("GameRecordSiteData"..num, encodeJson(data), totalRoundFileName) | |||
-- log("GameRecordController:writeSiteData end") | |||
-- local data = self:readSiteData(beginTime, self.m_totalTableId) | |||
-- log("xiabo_data", table.tostring(data)) | |||
end | |||
-- 每一场对应一个文件名,key值为beginTime和totalTableId,最近需要展示的数据对应的key值会保存在UserInfo中 | |||
function GameRecordController:readRoundData() | |||
-- log("GameRecordController:readRoundData") | |||
-- 先獲取場次數據 | |||
local GameRecordRoundNum = loadUserInfo("GameRecordRoundSumNum") | |||
-- log("xiabo_ss", GameRecordRoundNum) | |||
local GameRecordRoundDatas = {} | |||
if GameRecordRoundNum then | |||
GameRecordRoundNum = tonumber(GameRecordRoundNum) | |||
if GameRecordRoundNum and GameRecordRoundNum >= 1 then | |||
for i = 1, GameRecordRoundNum do | |||
-- log("xiabo", GameRecordRoundNum) | |||
local totalRoundData = loadUserInfo("GameRecordRoundData"..i) | |||
-- log("xiabo", type(totalRoundData)) | |||
if type(totalRoundData) == "string" then | |||
-- log("xiabo",totalRoundData) | |||
totalRoundData = decodeJson(totalRoundData) | |||
end | |||
-- log("xiabo", table.tostring(totalRoundData)) | |||
if type(totalRoundData) == "table" and next(totalRoundData) then | |||
totalRoundData.otherUserIds = decodeJson(totalRoundData.otherUserIds) | |||
totalRoundData.userNameMap = decodeJson(totalRoundData.userNameMap) | |||
end | |||
if totalRoundData and totalRoundData ~= "" then | |||
table.insert(GameRecordRoundDatas, totalRoundData) | |||
end | |||
end | |||
end | |||
end | |||
-- log("GameRecordController:readRoundData", table.tostring(GameRecordRoundDatas)) | |||
return GameRecordRoundDatas | |||
end | |||
function GameRecordController:writeRoundData() | |||
local value = { | |||
beginTime = loadUserInfo("GameRoundLastBeginTime"), | |||
totalTableId = self.m_totalTableId, | |||
myUserId = self.m_myUserId, | |||
otherUserIds = encodeJson(self.m_otherUserIds), | |||
totalMoney = self.m_totalMoney, | |||
totalGameNum = self.m_totalGameNum, | |||
userNameMap = encodeJson(self.m_userNameMap), | |||
} | |||
log("GameRecordController:writeRoundData", table.tostring(value)) | |||
-- 先獲取場次數據 | |||
local GameRecordRoundDatas = self:readRoundData() | |||
local haveThisData = false | |||
for k, v in pairs(GameRecordRoundDatas) do | |||
v.otherUserIds = encodeJson(v.otherUserIds) | |||
v.userNameMap = encodeJson(v.userNameMap) | |||
-- 如果有开始时间和桌数相同的,判断为同一轮 | |||
if v.beginTime == value.beginTime then | |||
haveThisData = true | |||
GameRecordRoundDatas[k] = value | |||
end | |||
end | |||
if not haveThisData then table.insert(GameRecordRoundDatas, value) end | |||
-- 排序,时间进的放前面,如果大于最高数,干掉后面的 | |||
local sortFun = function(list1, list2) | |||
return tonumber(list1.beginTime) > tonumber(list2.beginTime) | |||
end | |||
table.sort(GameRecordRoundDatas, sortFun) | |||
while #GameRecordRoundDatas > GameRecordController.k_max_record_num do | |||
-- 从列表中删除旧数据,并且刪除对应的XML文件 | |||
local removeData = table.remove(GameRecordRoundDatas) | |||
local removeBeginTime = removeData.beginTime | |||
local removeTotalTableId = removeData.totalTableId | |||
local removeFileName = "totalRoundFileName"..removeBeginTime..removeTotalTableId | |||
deleteXmlFile(removeFileName) | |||
end | |||
-- log("GameRecordRoundSumNum", #GameRecordRoundDatas) | |||
-- log("GameRecordRoundSumNum", table.tostring(GameRecordRoundDatas)) | |||
saveUserInfo("GameRecordRoundSumNum", #GameRecordRoundDatas) | |||
for k, v in pairs(GameRecordRoundDatas) do | |||
saveUserInfo("GameRecordRoundData" .. k, encodeJson(v)) | |||
end | |||
end |
@@ -0,0 +1,8 @@ | |||
local MailCmd = { | |||
PHP_GET_MESS = "message.getMess", --获取邮件 | |||
PHP_TAKE = "message.take", --领取奖励 | |||
PHP_DEL = "message.del", --删除邮件 | |||
PHP_READ = "message.setReadState", --阅读邮件 | |||
} | |||
return MailCmd |
@@ -0,0 +1,9 @@ | |||
local MailEvent = { | |||
UPDATE_MAIL = "UPDATE_MAIL", --获取邮件 | |||
PHP_TAKE = "message.take", --领取奖励 | |||
PHP_DEL = "message.del", --删除邮件 | |||
} | |||
return MailEvent |
@@ -0,0 +1,211 @@ | |||
local MailProtocolPhp = class("MailProtocolPhp") | |||
local MailCmd = require("luaScript.Protocol.Mail.MailCmd") | |||
local MailEvent = require("luaScript.Protocol.Mail.MailEvent") | |||
function MailProtocolPhp:ctor() | |||
-- 添加分发事件的组件 | |||
cc.GameObject.extend(self) | |||
self:addComponent(require("luaScript.cc.components.behavior.EventProtocol"):new()):exportMethods() | |||
self.mails={} | |||
end | |||
--发送请求 | |||
function MailProtocolPhp:post(action, param, callback) | |||
local phpAddress = app.config.RomSetting.phpUrl | |||
local msg = {} | |||
msg.action = action | |||
msg.uid = app.user.loginInfo.uid | |||
msg.app = getAppId() | |||
if param then | |||
table.merge(msg,param) | |||
end | |||
logD("MailProtocolPhp:post",table.tostring(msg)) | |||
httpPost(phpAddress, msg, function(status, response) | |||
if status == "failed" then | |||
showPHPFailedResult("请求数据失败! code = " .. response) | |||
else | |||
callback(response) | |||
end | |||
end) | |||
end | |||
--请求邮件 | |||
function MailProtocolPhp:requestMail(localData) | |||
local param = { | |||
id = #self.mails>0 and self.mails[#self.mails].id or 0, | |||
type = localData.type | |||
} | |||
self:post(MailCmd.PHP_GET_MESS,param,function(data) | |||
local response = json.decode(data) | |||
if type(response) ~= "table" then | |||
showPHPFailedResult("数据错误!") | |||
return | |||
end | |||
if cc.Application:getInstance():getTargetPlatform() == 0 then | |||
logD("MailProtocolPhp:requestMail",table.tostring(response)) | |||
end | |||
if response.code==200 then | |||
local result = response.result or {} | |||
self.mails = result | |||
self:dispatchEvent({name = MailEvent.UPDATE_MAIL}); | |||
else | |||
self:showError(MailCmd.PHP_GET_MESS,response.code,response) | |||
end | |||
end) | |||
end | |||
--阅读邮件 | |||
function MailProtocolPhp:requestReadMail(localData) | |||
local param = { | |||
ids = localData.ids, | |||
} | |||
self:post(MailCmd.PHP_READ,param,function(data) | |||
local response = json.decode(data) | |||
if type(response) ~= "table" then | |||
showPHPFailedResult("数据错误!") | |||
return | |||
end | |||
if cc.Application:getInstance():getTargetPlatform() == 0 then | |||
logD("MailProtocolPhp:requestMail",table.tostring(response)) | |||
end | |||
if response.code==200 then | |||
local result = response.result or {} | |||
local idList = string.split(result.ids,",") | |||
if idList then | |||
for k,v in ipairs(idList) do | |||
self:updateMailReadStatus(tonumber(v),result.flag) | |||
end | |||
self:dispatchEvent({name = MailEvent.UPDATE_MAIL}); | |||
end | |||
else | |||
self:showError(MailCmd.PHP_READ,response.code,response) | |||
end | |||
end) | |||
end | |||
function MailProtocolPhp:reciveMail(id) | |||
local param = { | |||
id = id | |||
} | |||
self:post(MailCmd.PHP_TAKE,param,function(data) | |||
local response = json.decode(data) | |||
if type(response) ~= "table" then | |||
showPHPFailedResult("数据错误!") | |||
return | |||
end | |||
if cc.Application:getInstance():getTargetPlatform() == 0 then | |||
logD("MailProtocolPhp:reciveMail",table.tostring(response)) | |||
end | |||
if response.code==200 then | |||
if response.result.flag==1 then | |||
self:updateMailStatus(response.result.id,1) | |||
showTooltip("领取成功,请到微信兑换红包!"); | |||
self:dispatchEvent({name = "reciveMail"}); | |||
self:dispatchEvent({name = "updateMail"}); | |||
else | |||
showTooltip("提取失败!code:"..response.result.flag); | |||
end | |||
else | |||
self:showError(MailCmd.PHP_TAKE,response.code,response) | |||
end | |||
end) | |||
end | |||
function MailProtocolPhp:delMail(ids) | |||
local param = { | |||
ids = ids | |||
} | |||
self:post(MailCmd.PHP_DEL,param,function(data) | |||
local response = json.decode(data) | |||
if type(response) ~= "table" then | |||
showPHPFailedResult("数据错误!") | |||
return | |||
end | |||
if cc.Application:getInstance():getTargetPlatform() == 0 then | |||
logD("MailProtocolPhp:reciveMail",table.tostring(response)) | |||
end | |||
if response.code==200 then | |||
if response.result.flag==1 then | |||
local ids=string.split(response.result.ids,",") | |||
for k,v in pairs(ids) do | |||
self:removeMailById(tonumber(v)) | |||
end | |||
showTooltip("删除成功!"); | |||
self:dispatchEvent({name = "updateMail"}); | |||
else | |||
showTooltip("删除失败! code:"..response.result.flag); | |||
end | |||
else | |||
self:showError(MailCmd.PHP_DEL,response.code,response) | |||
end | |||
end) | |||
end | |||
function MailProtocolPhp:isCanReciveById(id) | |||
for k,v in pairs(self.mails) do | |||
if v.id == id and v.awards and #v.awards>0 then | |||
for _,award in pairs(v.awards) do | |||
if award.havegot == 0 then | |||
return true | |||
end | |||
end | |||
end | |||
end | |||
return false | |||
end | |||
function MailProtocolPhp:isCanRecive() | |||
for k,v in pairs(self.mails) do | |||
if v.awards and #v.awards>0 then | |||
for _,award in pairs(v.awards) do | |||
if award.havegot == 0 then | |||
return true | |||
end | |||
end | |||
end | |||
end | |||
return false | |||
end | |||
function MailProtocolPhp:removeMailById(id) | |||
for k,v in pairs(self.mails) do | |||
if v.id == id then | |||
table.remove(self.mails,k) | |||
break | |||
end | |||
end | |||
end | |||
function MailProtocolPhp:updateMailStatus(id,status) | |||
for k,v in pairs(self.mails) do | |||
if v.id == id and v.awards and #v.awards>0 then | |||
for _,award in pairs(v.awards) do | |||
award.havegot=status | |||
end | |||
end | |||
end | |||
end | |||
function MailProtocolPhp:updateMailReadStatus(id,flag) | |||
local noReadCount = 0 | |||
for k,v in pairs(self.mails) do | |||
if v.id == id then | |||
v.read_state = flag | |||
end | |||
if tonumber(v.read_state) == 0 then | |||
noReadCount = noReadCount + 1 | |||
end | |||
end | |||
if noReadCount == 0 then | |||
app.msgManager:removeMsg(nil,ACTIVITY_REDPOINT.SYSTEM_MESSAGE) | |||
end | |||
end | |||
return MailProtocolPhp |
@@ -0,0 +1,326 @@ | |||
require("luaScript.Protocol.ProtocolCommon") | |||
local MatchCmd = require("luaScript.Protocol.Match.ProtocolMatchCmd") | |||
local MatchMessage = require("luaScript.Protocol.Match.ProtocolMatchMessage") | |||
local MatchDefined = require("luaScript.Views.Match.Constant.MatchDefined") | |||
local MatchEvents = require("luaScript.Views.Match.Constant.MatchEvents") | |||
local Match = class("Match" , require("luaScript.Protocol.Protocol")) | |||
function Match:ctor(net) | |||
Match.super.ctor(self , net); | |||
self.matchInfo={} | |||
self.matchInfo.matchList={} | |||
self.matchInfo.status=MatchDefined.MATCH_STATUS.DEFAULT | |||
self:initView() | |||
--发送 | |||
-- 进入比赛 | |||
self:defMsgFunc{name = MatchEvents.ENTER_MATCH , cmd = MatchCmd.CMD_MATCH_ENTER, sender = MatchMessage.MatchEnter}; | |||
-- 加入房间 | |||
-- self:defMsgFunc{name = "clubJoinRoomRequest" , cmd = MatchCmd.GAME_COMMAND_CLUB_JOINROOM_REQUEST, sender = ClubJoinRoomRequest}; | |||
--接收 | |||
-- 返回比赛列表信息 | |||
self:defPushMsg{cmd = MatchCmd.CMD_GET_LIST_RESPONSE , reader = MatchMessage.MatchGetListResponse, func = handler(self , self.getListResponse)} | |||
-- 报名成功 0x5007 | |||
self:defPushMsg{cmd = MatchCmd.CMD_SIGN_UP_ERROR_RESPONSE , reader = MatchMessage.MatchSignUpError, func = handler(self , self.signUpErrorResponse)} | |||
-- 报名失败 0x5006 | |||
self:defPushMsg{cmd = MatchCmd.CMD_SIGN_UP_SUCCESS_RESPONSE, reader = MatchMessage.MatchSignUpSuccess, func = handler(self, self.signUpSuccessResponse)} | |||
-- 报名信息更新 0x5018 | |||
self:defPushMsg{cmd = MatchCmd.CMD_SIGN_UP_INFO_RESPONSE, reader = MatchMessage.MatchSignUpInfo, func = handler(self, self.signUpInfoResponse)} | |||
-- 比赛开始 | |||
self:defPushMsg{cmd = MatchCmd.CMD_MATCH_START_RESPONSE, reader = MatchMessage.MatchStart, func = handler(self, self.matchStartResponse)} | |||
-- 比赛结束 | |||
self:defPushMsg{cmd = MatchCmd.CMD_MATCH_OVER_RESPONSE, func = handler(self, self.matchOverResponse)} | |||
-- 比赛异常结束 | |||
self:defPushMsg{cmd = MatchCmd.CMD_MATCH_EXCEPTION_RESPONSE, reader = MatchMessage.MatchException, func = handler(self, self.matchExceptionResponse)} | |||
-- 一轮结束 0x500e | |||
self:defPushMsg{cmd = MatchCmd.CMD_ROUND_OVER_RESPONSE, reader = MatchMessage.MacthRoundOver, func = handler(self, self.roundOverResponse)} | |||
-- 下一轮开始 0x5100 | |||
self:defPushMsg{cmd = MatchCmd.CMD_ROUND_START_RESPONSE, reader = MatchMessage.MatchRoundStart, func = handler(self, self.roundStartResponse)} | |||
-- 奖励信息 | |||
self:defPushMsg{cmd = MatchCmd.CMD_AWARD_INFO_RESPONSE, reader = MatchMessage.MatchAwardInfo, func = handler(self, self.awardInfoResponse)} | |||
-- 进入比赛失败 0x501a | |||
self:defPushMsg{cmd = MatchCmd.CMD_MATCH_ENTER_ERROR, reader = MatchMessage.MatchEnterError, func = handler(self, self.enterMatchError)} | |||
-- 进入比赛信息 0x501b | |||
self:defPushMsg{cmd = MatchCmd.CMD_MATCH_ENTER_INFO, reader = MatchMessage.MatchInfo, func = handler(self, self.enterMatchInfo)} | |||
-- 比赛已经开始 0x5015 | |||
self:defPushMsg{cmd = MatchCmd.CMD_MATCH_ALREADY_START, reader = MatchMessage.MatchAlreadyStart, func = handler(self, self.matchAlreadyStart)} | |||
-- 等待比赛开始 0x5017 | |||
self:defPushMsg{cmd = MatchCmd.CMD_MATCH_WAIT, reader = MatchMessage.MatchWait, func = handler(self, self.matchWait)} | |||
-- 排行榜 0x500f | |||
self:defPushMsg{cmd = MatchCmd.CMD_MATCH_RANK_RESPONSE, reader = MatchMessage.MatchRank, func = handler(self, self.matchRankResponse)} | |||
-- 排行推送 0x501c | |||
self:defPushMsg{cmd = MatchCmd.CMD_MATCH_PUSH_RANK, reader = MatchMessage.MatchPushRank, func = handler(self, self.matchPushRank)} | |||
end | |||
function Match:initView() | |||
self.MatchRoomWaitView = "zp_hsb.luaScript.Views.Match.yxhsbMatchRoomWaitView" | |||
end | |||
-- 获取比赛场列表 | |||
function Match:getListRequest(index) | |||
local request = MatchMessage.MatchGetList:new() | |||
request.uid = tonumber(app.user.loginInfo.uid) | |||
local appVersion = getAppVersionNum() | |||
local resVersion = loadVersion() | |||
request.version = appVersion.."."..resVersion | |||
request.areano = app.user.areano | |||
request.index = index or 0 | |||
dump(request) | |||
self:sendResponse({cmd = MatchCmd.CMD_GET_LIST , sender = request}) | |||
end | |||
-- 获取比赛场列表回调 | |||
function Match:getListResponse(status,response) | |||
logD("Match:getListResponse(), ", table.tostring(response)) | |||
self.matchInfo.isMatchListOver = response.isMatchListOver | |||
self.matchInfo.matchList = response.matchList | |||
self:dispatchEvent({name=MatchEvents.GET_LIST}) | |||
end | |||
--报名 | |||
function Match:signUp(data) | |||
local request = MatchMessage.MatchSignUp:new() | |||
request.gameId = data.gameId | |||
request.matchIndex = data.matchIndex | |||
request.matchType = data.matchType | |||
request.userInfo = app.user.userInfo | |||
dump(request) | |||
local matchInfo = self.matchInfo.matchList[data.matchIndex] | |||
local rewardInfo = json.decode(matchInfo.rewardInfo) | |||
self.matchInfo.rewards = rewardInfo.rewards | |||
self.matchInfo.matchName = matchInfo.matchName | |||
self.matchInfo.matchIndex = data.matchIndex | |||
self:sendResponse({cmd = MatchCmd.CMD_SIGN_UP , sender = request}) | |||
end | |||
--取消报名 | |||
function Match:signUpCancel() | |||
local request = MatchMessage.MatchSignUpCancel:new() | |||
request.uid = tonumber(app.user.loginInfo.uid) | |||
dump(request) | |||
self:sendResponse({cmd = MatchCmd.CMD_SIGN_UP_CANCEL , sender = request}) | |||
self:dispatchEvent({name = MatchEvents.SIGN_UP_CANCEL}) | |||
end | |||
--报名失败回调 | |||
function Match:signUpErrorResponse(status,response) | |||
logD("Match:signUpErrorResponse(), ", table.tostring(response)) | |||
-- 0, //服务器系统错误 1, //比赛信息错误 | |||
-- 2, //报名费不足 3, //比赛已经开始且不属于重连 | |||
-- 4, //玩家已經報名 | |||
if response.result==4 then | |||
self:dispatchEvent({name = MatchEvents.SIGN_UP_SUCCESS}) | |||
elseif response.result==2 then | |||
showTooltip("报名费不足!") | |||
end | |||
end | |||
--报名成功回调 | |||
function Match:signUpSuccessResponse(status,response) | |||
logD("Match:signUpSuccessResponse(), ", table.tostring(response)) | |||
self.matchInfo.curSignUpCnt=response.curSignUpCnt | |||
self.matchInfo.maxMatchCnt=response.maxMatchCnt | |||
self.matchInfo.status=MatchDefined.MATCH_STATUS.WAIT_START | |||
self.matchInfo.userScore=0 | |||
self.matchInfo.promotionInfo=response.promotionInfo | |||
self:dispatchEvent({name = MatchEvents.SIGN_UP_SUCCESS}) | |||
end | |||
--报名信息更新回调 | |||
function Match:signUpInfoResponse(status,response) | |||
logD("Match:signUpInfoResponse(), ", table.tostring(response)) | |||
self.matchInfo.curSignUpCnt=response.curSignUpCnt | |||
self.matchInfo.maxMatchCnt=response.maxMatchCnt | |||
self:dispatchEvent({name = MatchEvents.SIGN_UP_UPDATE}) | |||
end | |||
--比赛开始 | |||
function Match:matchStartResponse(status,response) | |||
logD("Match:matchStartResponse(), ", table.tostring(response)) | |||
self.matchInfo.rank=response.rank | |||
self.matchInfo.curRound=1 | |||
self.matchInfo.maxRound=response.maxRound | |||
self.matchInfo.promotionInfo=response.promotionInfo | |||
self.matchInfo.status=MatchDefined.MATCH_STATUS.GOING | |||
self:dispatchEvent({name = MatchEvents.MATCH_START}) | |||
end | |||
--比赛结束 | |||
function Match:matchOverResponse(status,response) | |||
logD("Match:matchOverResponse(), ", table.tostring(response)) | |||
setShowCountAll(false) | |||
app.net:runNextMsg() | |||
end | |||
--比赛异常结束 | |||
function Match:matchExceptionResponse(status,response) | |||
logD("Match:matchExceptionResponse(), ", table.tostring(response)) | |||
end | |||
--下一轮开始 | |||
function Match:roundStartResponse(status,response) | |||
logD("Match:roundStartResponse(), ", table.tostring(response)) | |||
self.matchInfo.rank=response.rank | |||
self.matchInfo.nextRound=response.nextRound | |||
self.matchInfo.curRound=response.nextRound | |||
self.matchInfo.maxRound=response.maxRound | |||
app.net:onMsgPause() | |||
self:dispatchEvent({name = MatchEvents.ROUND_NEXT,response=response}) | |||
end | |||
--一轮结束 | |||
function Match:roundOverResponse(status,response) | |||
logD("Match:roundOverResponse(), ", table.tostring(response)) | |||
self.matchInfo.rank=response.rank | |||
self.matchInfo.result=response.result | |||
-- Short notEndTableCnt; // 未结束的桌子数量 | |||
self.matchInfo.notEndTableCnt=response.notEndTableCnt | |||
-- Short curRound; //当前轮数 | |||
self.matchInfo.curRound=response.curRound | |||
-- Short maxRound; //总轮数 | |||
self.matchInfo.maxRound=response.maxRound | |||
-- Short maxMatchCnt; //总开赛人数 | |||
self.matchInfo.maxMatchCnt=response.maxMatchCnt | |||
self.matchInfo.promotionInfo=response.promotionInfo | |||
local rewardInfo = json.decode(response.rewardInfo) | |||
self.matchInfo.rewards = rewardInfo.rewards | |||
-- //1. 淘汰 2.晋级 3. 等待 | |||
if response.result==1 then | |||
self.matchInfo.status=MatchDefined.MATCH_STATUS.OUT | |||
else | |||
self.matchInfo.status=MatchDefined.MATCH_STATUS.WAIT_UP | |||
end | |||
app.net:onMsgPause() | |||
if app:getCurrentView().__cname=="MatchRoomWaitView" then | |||
self:dispatchEvent({name = MatchEvents.ROUND_OVER}) | |||
else | |||
local view = import(self.MatchRoomWaitView):new() | |||
app:gotoView(view) | |||
end | |||
end | |||
--奖励信息 | |||
function Match:awardInfoResponse(status,response) | |||
logD("Match:awardInfoResponse(), ", table.tostring(response)) | |||
self.matchInfo.rank=response.rank | |||
self.matchInfo.awardList=response.awardList | |||
self.matchInfo.status=MatchDefined.MATCH_STATUS.OVER | |||
self.matchInfo.userScore=response.userScore | |||
--没有奖励视为淘汰 | |||
if response.hasReward==0 then | |||
self.matchInfo.status=MatchDefined.MATCH_STATUS.OUT | |||
end | |||
local ttExtInfo = string.split(response.userExtInfo, ",") | |||
app.user.loginInfo.historyCardNum = ttExtInfo[1]; | |||
app.user.loginInfo.curCardNum = ttExtInfo[2]; | |||
local view = import(self.MatchRoomWaitView):new() | |||
app:gotoView(view) | |||
app.net:onMsgResume() | |||
-- self:dispatchEvent({name = MatchEvents.MATCH_OVER,response=response}) | |||
end | |||
function Match:enterMatchError(status,response) | |||
logD("Match:enterMatchError(), ", table.tostring(response)) | |||
app.waitDialogManager:closeWaitNetworkDialog(); | |||
gotoMainView(); | |||
end | |||
function Match:enterMatchInfo(status,response) | |||
logD("Match:enterMatchInfo(), ", table.tostring(response)) | |||
app.waitDialogManager:closeWaitNetworkDialog(); | |||
self.matchInfo.gameId=response.gameId | |||
self.matchInfo.tableId=response.tableId | |||
self.matchInfo.gameInfo=response.gameInfo | |||
self.matchInfo.matchStatus=response.matchStatus | |||
self.matchInfo.matchIndex = response.matchIndex | |||
-- self.matchInfo.rank=response.rank | |||
-- self.matchInfo.tableList=response.tableList | |||
--1比赛开始 | |||
if response.matchStatus==1 then | |||
app:changeGameProtocol(2,0,PROTOCOL_TYPE.MATCH) | |||
else | |||
-- local view = import("Views.Match.MatchRoomWaitView"):new() | |||
-- app:gotoView(view) | |||
end | |||
end | |||
function Match:matchAlreadyStart(status,response) | |||
logD("Match:matchAlreadyStart(), ", table.tostring(response)) | |||
self.matchInfo.curRound=response.curRound | |||
self.matchInfo.curRoundJuShu=response.curRoundJuShu | |||
self.matchInfo.maxMatchCnt=response.maxMatchCnt | |||
self.matchInfo.maxRound=response.maxRound | |||
self.matchInfo.rank=response.rank | |||
self.matchInfo.tableList=response.tableList | |||
self.matchInfo.promotionInfo=response.promotionInfo | |||
self.matchInfo.matchName=response.matchName | |||
local rewardInfo = json.decode(response.rewardInfo) | |||
self.matchInfo.rewards = rewardInfo.rewards | |||
self.matchInfo.status=MatchDefined.MATCH_STATUS.GOING | |||
end | |||
function Match:matchWait(status,response) | |||
logD("Match:matchWait(), ", table.tostring(response)) | |||
self.matchInfo.curSignUpCnt=response.curSignUpCnt | |||
self.matchInfo.maxMatchCnt=response.maxMatchCnt | |||
self.matchInfo.matchType=response.matchType | |||
self.matchInfo.matchName=response.matchName | |||
self.matchInfo.promotionInfo=response.promotionInfo | |||
local rewardInfo = json.decode(response.rewardInfo) | |||
self.matchInfo.rewards = rewardInfo.rewards | |||
self.matchInfo.status=MatchDefined.MATCH_STATUS.WAIT_START | |||
local view = import(self.MatchRoomWaitView):new() | |||
app:gotoView(view) | |||
end | |||
--请求排行榜 | |||
function Match:matchRank() | |||
local request = MatchMessage.MatchSignUpCancel:new() | |||
request.uid = tonumber(app.user.loginInfo.uid) | |||
dump(request) | |||
self:sendResponse({cmd = MatchCmd.CMD_MATCH_RANK , sender = request}) | |||
end | |||
--请求排行榜 回调 | |||
function Match:matchRankResponse(status,response) | |||
logD("Match:matchRankResponse(), ", table.tostring(response)) | |||
self.matchInfo.rank=response.rank | |||
self.matchInfo.rankList=response.rankList | |||
self:dispatchEvent({name = MatchEvents.MATCH_RANK}) | |||
end | |||
function Match:matchPushRank(status,response) | |||
logD("Match:matchPushRank(), ", table.tostring(response)) | |||
if app.user.loginInfo.uid==response.uid then | |||
self.matchInfo.rank=response.rank | |||
self.matchInfo.maxMatchCnt=response.maxMatchCnt | |||
end | |||
self:dispatchEvent({name = MatchEvents.MATCH_PUSH_RANK}) | |||
end | |||
return Match; |
@@ -0,0 +1,66 @@ | |||
-- 命令集合 | |||
local MatchCmd = { | |||
--获取比赛列表 | |||
CMD_GET_LIST=0x5000, | |||
--返回比赛列表信息 | |||
CMD_GET_LIST_RESPONSE=0x5001, | |||
--报名 | |||
CMD_SIGN_UP=0x5005, | |||
--取消报名 | |||
CMD_SIGN_UP_CANCEL=0x5008, | |||
--报名失败 | |||
CMD_SIGN_UP_ERROR_RESPONSE=0x5006, | |||
--报名成功 | |||
CMD_SIGN_UP_SUCCESS_RESPONSE=0x5007, | |||
--收到新报名信息 | |||
CMD_SIGN_UP_INFO_RESPONSE=0x5018, | |||
--比赛开始 | |||
CMD_MATCH_START_RESPONSE=0x500b, | |||
--比赛结束 | |||
CMD_MATCH_OVER_RESPONSE=0x5011, | |||
--比赛异常结束 | |||
CMD_MATCH_EXCEPTION_RESPONSE=0x5013, | |||
--一轮结束 | |||
CMD_ROUND_OVER_RESPONSE=0x500e, | |||
--下一轮开始 | |||
CMD_ROUND_START_RESPONSE=0x5010, | |||
--奖励信息 | |||
CMD_AWARD_INFO_RESPONSE=0x5012, | |||
--进入比赛 | |||
CMD_MATCH_ENTER=0x5019, | |||
--进入比赛失败 | |||
CMD_MATCH_ENTER_ERROR=0x501a, | |||
--进入比赛信息 | |||
CMD_MATCH_ENTER_INFO=0x501b, | |||
--比赛已经开始 | |||
CMD_MATCH_ALREADY_START=0x5015, | |||
--等待比赛开始 | |||
CMD_MATCH_WAIT=0x5017, | |||
CMD_MATCH_RANK=0x5014, | |||
CMD_MATCH_RANK_RESPONSE=0x500f, | |||
--结算推送排名 | |||
CMD_MATCH_PUSH_RANK=0x501c, | |||
} | |||
return MatchCmd |
@@ -0,0 +1,336 @@ | |||
local message = {} | |||
--获取比赛列表 | |||
message.MatchGetList = defClass("MatchGetList" | |||
--玩家id | |||
, defVar("uid", VT_Int, 0) | |||
--客户端版本 | |||
, defVar("version", VT_String, "") | |||
--/地区id | |||
, defVar("areano", VT_Short, 1) | |||
--拉取位置 | |||
, defVar("index", VT_Short, 0) | |||
) | |||
--比赛列表数据 | |||
message.MatchListItem = defClass("MatchListItem" | |||
-- int matchIndex; //比赛编号,服务器生产唯一标识 | |||
, defVar("matchIndex", VT_Int, 0) | |||
-- short signUpCnt; //已报名人数 | |||
, defVar("signUpCnt", VT_Short, 0) | |||
-- Short maxMatchCnt; //比赛开赛人数 | |||
, defVar("maxMatchCnt", VT_Short, 0) | |||
-- Short gameId; //游戏id | |||
, defVar("gameId", VT_Short, 0) | |||
-- Short matchType; //比赛类型 | |||
, defVar("matchType", VT_Short, 0) | |||
-- String matchName; //比赛名称 | |||
, defVar("matchName", VT_String, "") | |||
-- String matchDes; //比赛描述 | |||
, defVar("matchDes", VT_String, "") | |||
-- String rewardInfo; //比赛奖励信息,json格式 | |||
, defVar("rewardInfo", VT_String, "") | |||
-- String signupInfo; //比赛报名条件 json格式 | |||
, defVar("signupInfo", VT_String, "") | |||
-- String otherInfo; //其他信息,json个数待扩展 | |||
, defVar("otherInfo", VT_String, "") | |||
) | |||
--获取比赛列表回调 | |||
message.MatchGetListResponse = defClass("MatchGetListResponse" | |||
--//比赛列表是否结束 | |||
, defVar("isMatchListOver", VT_Byte, "") | |||
--比赛列表 | |||
, defVar("matchList", VT_VectorToMap(message.MatchListItem,"matchIndex"), {}) | |||
) | |||
--报名 | |||
message.MatchSignUp = defClass("MatchSignUp" | |||
-- Short gameId; //游戏id | |||
, defVar("gameId", VT_Short, 0) | |||
-- Int mathIndex; //比赛编号 | |||
, defVar("matchIndex", VT_Int, 0) | |||
-- Short matchType; //比赛类型 | |||
, defVar("matchType", VT_Short, 0) | |||
-- String userInfo; //json格式, 用户信息如昵称,头像等 | |||
, defVar("userInfo", VT_String, "") | |||
) | |||
--报名取消 | |||
message.MatchSignUpCancel = defClass("MatchSignUpCancel" | |||
-- Int uid; //玩家id | |||
, defVar("uid", VT_Int, 0) | |||
) | |||
--报名失败 | |||
message.MatchSignUpError = defClass("MatchSignUpError" | |||
-- Short result; | |||
-- 0, //服务器系统错误 | |||
-- 1, //比赛信息错误 | |||
-- 2, //报名费不足 | |||
-- 3, //比赛已经开始且不属于重连 | |||
-- 4, //玩家已經報名 | |||
, defVar("result", VT_Short, 0) | |||
) | |||
--报名成功 | |||
message.MatchSignUpSuccess = defClass("MatchSignUpSuccess" | |||
-- Short curSignUpCnt; //当前报名人数 | |||
, defVar("curSignUpCnt", VT_Short, 0) | |||
-- Short maxMatchCnt; //总开赛人数 | |||
, defVar("maxMatchCnt", VT_Short, 0) | |||
-- String strExtInfo; //用户金币信息,同登录返回格式 | |||
, defVar("strExtInfo", VT_String, 0) | |||
-- String promotionInfo; //晋级信息,例如”9,6,3” 表示9进6 ,6进3,最后3人决赛 | |||
, defVar("promotionInfo", VT_String, "") | |||
) | |||
--报名更新信息 | |||
message.MatchSignUpInfo = defClass("MatchSignUpInfo" | |||
-- Short curSignUpCnt; //当前报名人数 | |||
, defVar("curSignUpCnt", VT_Short, 0) | |||
-- Short maxMatchCnt; //总开赛人数 | |||
, defVar("maxMatchCnt", VT_Short, 0) | |||
) | |||
--比赛异常结束 | |||
message.MatchException = defClass("MatchException" | |||
-- Byte errCode; //错误原因,取值如下 | |||
-- { | |||
-- WAIT_LONG_TIME = 1, //长时间未开始游戏 | |||
-- MATCH_START_ERROR = 2, //比赛开始异常 | |||
-- MATCH_CONTINUE_ERROR = 3, //比赛继续异常 | |||
-- MATCH_LONG_TIME_NOT_END = 4, //比赛长时间未结束 | |||
-- } | |||
, defVar("errCode", VT_Byte, 0) | |||
-- String userExtInfo; //用户货币信息,同登录格式 | |||
, defVar("strExtInfo", VT_String, 0) | |||
) | |||
--一轮结束 | |||
message.MacthRoundOver = defClass("MacthRoundOver" | |||
-- Short rank; //桌子上排名 | |||
, defVar("rank", VT_Short, 0) | |||
-- Byte result; //1. 淘汰 2.晋级 3. 等待 | |||
, defVar("result", VT_Byte, 0) | |||
-- Short notEndTableCnt; // 未结束的桌子数量 | |||
, defVar("notEndTableCnt", VT_Short, 0) | |||
-- Short curRound; //当前轮数 | |||
, defVar("curRound", VT_Short, 0) | |||
-- Short maxRound; //总轮数 | |||
, defVar("maxRound", VT_Short, 0) | |||
-- Short maxMatchCnt; //总开赛人数 | |||
, defVar("maxMatchCnt", VT_Short, 0) | |||
-- String promotionInfo; //晋级信息,例如”9,6,3” 表示9进6 ,6进3,最后3人决赛 | |||
, defVar("promotionInfo", VT_String, "") | |||
-- String rewardInfo; //比赛奖励信息 | |||
, defVar("rewardInfo", VT_String, 0) | |||
) | |||
--一轮开始桌子信息 | |||
message.MatchRoundTableItem = defClass("MatchRoundTableItem" | |||
-- int uid ; //桌子玩家id | |||
, defVar("uid", VT_Int, 0) | |||
-- Int lastScore; //上轮积分 | |||
, defVar("lastScore", VT_Int, 0) | |||
-- Int score; //玩家积分 | |||
, defVar("score", VT_Int, 0) | |||
-- String userInfo; //玩家昵称、头像等信息 | |||
, defVar("userInfo", VT_String, "") | |||
) | |||
--一轮开始 | |||
message.MatchRoundStart = defClass("MatchRoundStart" | |||
-- Short nextRound; //下轮轮数 | |||
, defVar("nextRound", VT_Short, 0) | |||
-- Short maxRound; //总轮数 | |||
, defVar("maxRound", VT_Short, 0) | |||
-- Short rank; //下轮在桌子上的排名 | |||
, defVar("rank", VT_Short, 0) | |||
-- Short tableMaxUserCnt; //桌子最大人数 | |||
-- { | |||
-- int uid ; //桌子玩家id | |||
-- Int score; //玩家积分 | |||
-- String userInfo; //玩家昵称、头像等信息 | |||
-- } | |||
, defVar("tableList", VT_Vector(message.MatchRoundTableItem), {}) | |||
) | |||
--奖励信息条目 | |||
message.MatchAwardInfoItem = defClass("MatchAwardInfoItem" | |||
-- Int type; //奖品类型,1: 金币 13:房卡(暂支持两种) | |||
, defVar("type", VT_Int, 0) | |||
-- Int num; //奖品个数 | |||
, defVar("num", VT_Int, 0) | |||
-- String otheInfo; //奖品其他信息,待扩展 | |||
, defVar("otheInfo", VT_String, "") | |||
) | |||
--奖励信息 | |||
message.MatchAwardInfo = defClass("MatchAwardInfo" | |||
-- Short gameId; //游戏id | |||
, defVar("gameId", VT_Short, 0) | |||
-- Short hasReward; //是否得奖 0: 无 1:有 | |||
, defVar("hasReward", VT_Short, 0) | |||
-- Short rank; //名次 | |||
, defVar("rank", VT_Short, 0) | |||
-- Short maxmaxMatchCnt; //总参数人数 | |||
, defVar("maxMatchCnt", VT_Short, 0) | |||
-- Short userExtInfo; // 用户货币信息,同登录格式 | |||
, defVar("userExtInfo", VT_String, 0) | |||
-- Short rewardCnt; //奖品个数 | |||
-- { | |||
-- Int type; //奖品类型,1: 金币 13:房卡(暂支持两种) | |||
-- Int num; //奖品个数 | |||
-- String otheInfo; //奖品其他信息,待扩展 | |||
-- } | |||
, defVar("awardList", VT_Vector(message.MatchAwardInfoItem), {}) | |||
, defVar("userScore", VT_Short, 0) | |||
) | |||
message.MatchEnter = defClass("MatchEnter" | |||
-- Int uid; //用户id | |||
, defVar("uid", VT_Int, 0) | |||
-- String userInfo; //用户信息 | |||
, defVar("userInfo", VT_String, 0) | |||
) | |||
message.MatchInfo = defClass("MatchInfo" | |||
-- Int gameId; //游戏id | |||
, defVar("gameId", VT_Int, 0) | |||
-- Short matchStatus; //比赛状态, 0:未开始 1:已开始 | |||
, defVar("matchStatus", VT_Short, 0) | |||
-- Int tableId; //桌子id, 若为0表示没有开始游戏,不为0说明在比赛游戏中 | |||
, defVar("tableId", VT_Int, 0) | |||
-- String gameInfo; //游戏参数信息,json格式 | |||
, defVar("gameInfo", VT_String, 0) | |||
-- Int mathIndex; //比赛编号 | |||
, defVar("matchIndex", VT_Int, 0) | |||
) | |||
message.MatchAlreadyStartItem = defClass("MatchAlreadyStartItem" | |||
-- int uid ; //桌子玩家id | |||
, defVar("uid", VT_Int, 0) | |||
-- Int lastScore; //上轮积分 | |||
-- , defVar("lastScore", VT_Int, 0) | |||
-- Int score; //玩家积分 | |||
, defVar("score", VT_Int, 0) | |||
-- String userInfo; //玩家昵称、头像等信息 | |||
, defVar("userInfo", VT_String, "") | |||
) | |||
message.MatchAlreadyStart = defClass("MatchAlreadyStart" | |||
-- Short curRound; //当前比赛轮数 | |||
, defVar("curRound", VT_Short, 0) | |||
-- Short maxMatchCnt; //比赛人数 | |||
, defVar("maxMatchCnt", VT_Short, 0) | |||
-- Short rank; //当前桌子排名 | |||
, defVar("rank", VT_Short, 0) | |||
-- Short userCnt; //桌子上人数 | |||
-- { | |||
-- Int uid; | |||
-- Int score; | |||
-- String usrInfo; | |||
-- } | |||
, defVar("tableList", VT_Vector(message.MatchAlreadyStartItem), {}) | |||
-- Short curRoundJuShu; //当前轮数有多少局 | |||
, defVar("curRoundJuShu", VT_Short, 0) | |||
-- Short maxRound; //总的轮数 | |||
, defVar("maxRound", VT_Short, 0) | |||
, defVar("promotionInfo", VT_String, "") | |||
, defVar("matchName", VT_String, "") | |||
-- String rewardInfo; //比赛奖励信息 | |||
, defVar("rewardInfo", VT_String, 0) | |||
) | |||
--报名失败 | |||
message.MatchEnterError = defClass("MatchEnterError" | |||
-- Byte resultCode; //错误码 | |||
-- { | |||
-- USER_NOT_LOGIN = 1, //未报名比赛或者已经被淘汰 | |||
-- SYSTEM_FATAL_ERROR = 2, //系统错误 | |||
-- USER_NOT_EXSIST = 3, //用户不存在 | |||
-- } | |||
, defVar("resultCode", VT_Byte, 0) | |||
) | |||
message.MatchWait = defClass("MatchWait" | |||
-- Short gameId; | |||
, defVar("gameId", VT_Short, 0) | |||
-- Short curSignUpCnt; //当前已报名玩家个数 | |||
, defVar("curSignUpCnt", VT_Short, 0) | |||
-- Short maxmaxMatchCnt; //比赛最大报名人数 | |||
, defVar("maxMatchCnt", VT_Short, 0) | |||
-- Byte matchType; //比赛类型 | |||
, defVar("matchType", VT_Byte, 0) | |||
-- String rewardInfo; //比赛奖励信息 | |||
, defVar("rewardInfo", VT_String, 0) | |||
, defVar("matchName", VT_String, "") | |||
-- String promotionInfo; //晋级信息,例如”9,6,3” 表示9进6 ,6进3,最后3人决赛 | |||
, defVar("promotionInfo", VT_String, "") | |||
) | |||
message.MatchStart = defClass("MatchStart" | |||
-- Int uid; | |||
, defVar("uid", VT_Int , 0) | |||
-- Short rank; //排名 | |||
, defVar("rank", VT_Short , 0) | |||
-- Short maxRound; //总的轮数 | |||
, defVar("maxRound", VT_Short, 0) | |||
-- String promotionInfo; //晋级信息,例如”9,6,3” 表示9进6 ,6进3,最后3人决赛 | |||
, defVar("promotionInfo", VT_String, "") | |||
) | |||
message.MatchRankItem = defClass("MatchRankItem" | |||
-- Short rank; | |||
, defVar("rank", VT_Short , 0) | |||
-- Int uid; | |||
, defVar("uid", VT_Int , 0) | |||
-- Int score; | |||
, defVar("score", VT_Int , 0) | |||
-- String strUserInfo; //用户信息 | |||
, defVar("strUserInfo", VT_String , 0) | |||
) | |||
--排行榜 | |||
message.MatchRank = defClass("MatchRank" | |||
-- Short rank; //请求玩家排名 | |||
, defVar("rank", VT_Short , 0) | |||
-- Short maxMatchCnt; //比赛总人数 | |||
, defVar("maxMatchCnt", VT_Short , 0) | |||
-- Shor rankUserCnt | |||
-- { | |||
-- Short rank; | |||
-- Int uid; | |||
-- Int score; | |||
-- String strUserInfo; //用户信息 | |||
-- } | |||
, defVar("rankList", VT_Vector(message.MatchRankItem), {}) | |||
) | |||
message.MatchPushRank = defClass("MatchPushRank" | |||
-- Int uid; //id | |||
, defVar("uid", VT_Int , 0) | |||
-- Short rank; //排名 | |||
, defVar("rank", VT_Short , 0) | |||
-- Short maxMatchCnt; //比赛总人数 | |||
, defVar("maxMatchCnt", VT_Short , 0) | |||
) | |||
return message |
@@ -0,0 +1,38 @@ | |||
--- 金币场相关PHP请求接口 | |||
local ProtocolMatchPhp = class("ProtocolMatchPhp") | |||
local UserCmd = { | |||
PHP_MATCH_RECORD = "matchrecord.record", -- 比赛记录 | |||
} | |||
--- ProtocolMatchPhp:ctor | |||
function ProtocolMatchPhp:ctor() | |||
self.phpUrl = getGlobalPhpUrl() | |||
self.matchRecrods = {} | |||
end | |||
-- 获取比赛记录 | |||
function ProtocolMatchPhp:requestMatchRecrod() | |||
local params = | |||
{ | |||
action = UserCmd.PHP_MATCH_RECORD, | |||
uid = app.user.loginInfo.uid, | |||
} | |||
print("ProtocolMatchPhp:requestMatchRecrod() ", table.tostring(params)) | |||
httpPost(self.phpUrl, params, function (status, response) | |||
if status ~= "successed" then | |||
return | |||
end | |||
local data = json.decode(response) | |||
if not data then | |||
return | |||
end | |||
if data.code==200 then | |||
self.matchRecrods=data.result.data or {} | |||
app:dispatchEvent({name = "matchRecrod"}); | |||
end | |||
end) | |||
end | |||
return ProtocolMatchPhp |
@@ -0,0 +1,28 @@ | |||
-- 模块宏 | |||
local ModuleName = { | |||
--[[ | |||
* 测试用 | |||
* <pre> | |||
* 协议测试. | |||
* 数据测试. | |||
* </pre> | |||
--]] | |||
TEST = 0; | |||
--[[ | |||
* 基础模块 | |||
* <pre> | |||
* 心跳. | |||
* </pre> | |||
--]] | |||
BASE = 1; | |||
--[[ | |||
* 用户模块 | |||
--]] | |||
USER = 99; | |||
} | |||
return ModuleName; |
@@ -0,0 +1,433 @@ | |||
-- 是否显示解析协议的具体信息 | |||
local showNetLog = true; | |||
VT_None = 0; | |||
-- bool,1字节 | |||
VT_Bool = 1; | |||
-- 无符号uchar,1字节,对应java的byte | |||
VT_UChar = 2; | |||
-- 有符号char,1字节,对应java的byte | |||
VT_Char = 3; | |||
-- 有符号short,2字节 | |||
VT_Short = 4; | |||
-- 无符号ushort,2字节 | |||
VT_UShort = 5; | |||
-- 有符号int,4字节 | |||
VT_Int = 6; | |||
-- 无符号uint,4字节 | |||
VT_UInt = 7; | |||
-- 浮点数,4字节 | |||
VT_Float = 8; | |||
-- 长整形,int64,8字节,对应java的long | |||
VT_LLong = 9; | |||
-- 字符串,使用UTF8编码,先保存2字节长度,再保存字符串数据 | |||
VT_String = 10; | |||
-- 双精度浮点数 | |||
VT_Double = 11; | |||
-- 二进制数据,先保存4个字节长度,再保存数据 | |||
VT_Buffer = 12; | |||
VT_Byte = VT_Char; | |||
VT_Long = VT_LLong; | |||
-- 保存所有简单类型 | |||
local gSimpleNetVarType = {} | |||
for i = 1 , 12 do | |||
gSimpleNetVarType[i] = cc.SimpleNetVar:create(i); | |||
gSimpleNetVarType[i]:retain(); | |||
autoGC(gSimpleNetVarType[i]); | |||
end | |||
-- 保存所有全局类 | |||
local gNetClassType = {} | |||
-- 获取网络数据类型 | |||
function getVarType(t) | |||
if type(t) == "number" then | |||
local simpleType = gSimpleNetVarType[t]; | |||
assert(simpleType); | |||
return simpleType; | |||
else | |||
assert(t); | |||
return t; | |||
end | |||
end | |||
local newBindableArray = require("luaScript.Protocol.BindableArray") | |||
local function tableNewHook(tab , cls) | |||
local ret = newBindableArray(tab); | |||
rawset(ret , "NetVar" , cls); | |||
return ret; | |||
end | |||
local function tableReadHook(tab , cls) | |||
local ret = newBindableArray(tab); | |||
rawset(ret , "NetVar" , cls); | |||
return ret; | |||
end | |||
local function tableWriteHook(tab , cls) | |||
return rawget(tab , "Datas"); | |||
end | |||
-- Map类型 | |||
function VT_Map(keyType , valueType) | |||
local var = cc.MapNetVar:create(getVarType(keyType) , getVarType(valueType)); | |||
var:setNewHookFunc(tableNewHook); | |||
var:setReadHookFunc(tableReadHook); | |||
var:setWriteHookFunc(tableWriteHook); | |||
return var; | |||
end | |||
-- Vector类型 | |||
function VT_Vector(valueType) | |||
local var = cc.VectorNetVar:create(getVarType(valueType)); | |||
var:setNewHookFunc(tableNewHook); | |||
var:setReadHookFunc(tableReadHook); | |||
var:setWriteHookFunc(tableWriteHook); | |||
return var; | |||
end | |||
-- Vector类型 | |||
function VT_VectorToSet(valueType , defaultValue) | |||
local var = cc.VectorToSetNetVar:create(getVarType(valueType) , defaultValue); | |||
var:setNewHookFunc(tableNewHook); | |||
var:setReadHookFunc(tableReadHook); | |||
var:setWriteHookFunc(tableWriteHook); | |||
return var; | |||
end | |||
-- Vector类型 | |||
function VT_VectorToMap(valueType , mapKeyName) | |||
assert(type(mapKeyName) == "string"); | |||
local var = cc.VectorToMapNetVar:create(getVarType(valueType) , mapKeyName); | |||
var:setNewHookFunc(tableNewHook); | |||
var:setReadHookFunc(tableReadHook); | |||
var:setWriteHookFunc(tableWriteHook); | |||
return var; | |||
end | |||
-- 由用户决定读写函数 | |||
function VT_Custom(name , newFunc , readFunc , writeFunc) | |||
assert(type(name) == "string" and type(newFunc) == "function" and type(readFunc) == "function" and type(writeFunc) == "function"); | |||
return cc.CustomNetVar:create(name , newFunc , readFunc , writeFunc); | |||
end | |||
function VT_CustomVectorToMap(valueType , mapKeyName) | |||
assert(type(mapKeyName) == "string"); | |||
local var = cc.CustomToMapNetVar:create(getVarType(valueType), mapKeyName); | |||
var:setNewHookFunc(tableNewHook); | |||
var:setReadHookFunc(tableReadHook); | |||
var:setWriteHookFunc(tableWriteHook); | |||
return var; | |||
end | |||
-- 定义一个枚举 | |||
function VT_Enum(name , valueType , values) | |||
assert(type(name) == "string" and type(values) == "table"); | |||
local enumVar = cc.EnumNetVar:create(name , getVarType(valueType)); | |||
for i , v in pairs(values) do | |||
enumVar:addValue(i , v); | |||
end | |||
return enumVar; | |||
end | |||
-- 属性ID | |||
function VT_PropertyID(classTable) | |||
assert(tolua.type(classTable) == "cc.NetClass"); | |||
return cc.PropertyIdNetVar:create(classTable); | |||
end | |||
-- 属性,需要传一个类的名字进来,属性最终序列化会变成一个属性ID+属性值(根据不同属性长度会不同) | |||
function VT_Property(classTable) | |||
assert(tolua.type(classTable) == "cc.NetClass"); | |||
return cc.PropertyNetVar:create(classTable); | |||
end | |||
local function VT_MapPropertytableReadHook(tab , cls) | |||
local ret = newBindableArray(tab); | |||
rawset(ret , "NetVar" , cls); | |||
return ret; | |||
end | |||
-- 属性映射表类型 | |||
function VT_MapProperty(classTable) | |||
assert(tolua.type(classTable) == "cc.NetClass"); | |||
local var = cc.MapPropertyNetVar:create(classTable); | |||
var:setNewHookFunc(tableNewHook); | |||
var:setReadHookFunc(VT_MapPropertytableReadHook); | |||
var:setWriteHookFunc(tableWriteHook); | |||
return var; | |||
end | |||
local RemainTime = require("luaScript.Protocol.RemainTime") | |||
function VT_RemainTime(numberType, scaler, onTimeOver) | |||
local numberNetVar = getVarType(numberType); | |||
local function newRemainTime() | |||
return RemainTime:new(); | |||
end | |||
local function newFunc(defaultValue) | |||
local instance = newRemainTime(); | |||
if type(defaultValue) == "number" then | |||
instance:setRemainTime(defaultValue); | |||
end | |||
return instance; | |||
end | |||
local function readFunc(stream) | |||
local remainTime = NetStream.readNetVar(numberNetVar , stream) | |||
local instance = newRemainTime(); | |||
instance:setRemainTime(remainTime / scaler); | |||
return instance | |||
end | |||
local function writeFunc(value , stream) | |||
NetStream.writeNetVar(numberNetVar , stream , value.RemainTime * scaler) | |||
end | |||
return VT_Custom("VT_RemainTime" , newFunc , readFunc , writeFunc); | |||
end | |||
-- 从NetStream解析出一个类 | |||
function cc.NetClass:tryRead(stream) | |||
local result; | |||
local errorMessage; | |||
function readIt() | |||
cc.NetVar:setLogEnabled(showNetLog); | |||
result = NetStream.readNetVar(self , stream); | |||
end | |||
function onError(msg) | |||
errorMessage = msg; | |||
print("读取数据时发生了错误:" , msg); | |||
cc.NetVar:setLogEnabled(showNetLog); | |||
end | |||
xpcall(readIt, onError) | |||
return result; | |||
end | |||
-- 从NetStream解析出一个类 | |||
function cc.NetClass:read(stream) | |||
local result; | |||
local errorMessage; | |||
function readIt() | |||
cc.NetVar:setLogEnabled(showNetLog); | |||
result = NetStream.readNetVar(self , stream); | |||
end | |||
function onError(msg) | |||
errorMessage = msg; | |||
cc.NetVar:setLogEnabled(showNetLog); | |||
print("读取数据时发生了错误,尝试以详细输出方式读取:" , msg); | |||
NetStream.reset(stream); | |||
xpcall(readIt, | |||
function(msg) | |||
cc.NetVar:setLogEnabled(showNetLog); | |||
print(msg) | |||
end | |||
) | |||
cc.NetVar:setLogEnabled(showNetLog); | |||
end | |||
xpcall(readIt, onError) | |||
cc.NetVar:setLogEnabled(showNetLog); | |||
--readIt(); | |||
if errorMessage then | |||
error(errorMessage); | |||
end | |||
return result; | |||
end | |||
-- 创建类实例 | |||
function cc.NetClass:new() | |||
local object = NetStream.newNetVar(self); | |||
return object; | |||
end | |||
-- 把类实例写入到stream | |||
function cc.NetClass:write(stream , object) | |||
NetStream.writeNetVar(self , stream , object); | |||
end | |||
-- 把类实例发送到服务器 | |||
function cc.NetClass:send(object , moduleID , commandID, net) | |||
local stream = NetStream.new(); | |||
self:write(stream , object); | |||
net:send(moduleID , commandID , stream); | |||
NetStream.delete(stream); | |||
end | |||
-- 保存到字符串 | |||
function cc.NetClass:saveToString(object) | |||
local stream = NetStream.new(); | |||
self:write(stream , object); | |||
local data = NetStream.getWriteData(stream); | |||
NetStream.delete(stream); | |||
return data; | |||
end | |||
-- 从字符串载入类 | |||
function cc.NetClass:loadFromString(stringData) | |||
local stream = NetStream.new(stringData); | |||
local responseInfo = self:read(stream); | |||
NetStream.delete(stream); | |||
return responseInfo; | |||
end | |||
-- 保存到文件 | |||
function cc.NetClass:saveToFile(object , filename) | |||
local stream = NetStream.new(); | |||
self:write(stream , object); | |||
local data = NetStream.getWriteData(stream); | |||
local f = io.open(filename , "wb"); | |||
if f then | |||
f:write(data); | |||
f:close(); | |||
end | |||
NetStream.delete(stream); | |||
return data; | |||
end | |||
-- 从文件载入类 | |||
function cc.NetClass:loadFromFile(filename) | |||
local f , err = io.open(filename , "rb"); | |||
if not f then | |||
return f , err; | |||
end | |||
local stringData = f:read("*a"); | |||
f:close(); | |||
local stream = NetStream.new(stringData); | |||
local responseInfo = self:read(stream); | |||
NetStream.delete(stream); | |||
return responseInfo; | |||
end | |||
-- 克隆一份 | |||
function cc.NetClass:clone(object) | |||
assert(object); | |||
local stream = NetStream.new(); | |||
self:write(stream , object); | |||
local responseInfo = self:read(stream); | |||
NetStream.delete(stream); | |||
return responseInfo; | |||
end | |||
-- 定义一个成员变量 | |||
function defVar(name , valueType , defaultValue , propId , minVersion) | |||
return cc.MemberVar:create(name , getVarType(valueType) , propId or -1 , defaultValue , true , minVersion or 0); | |||
end | |||
-- 定义一个本地成员变量(不序列化到网络) | |||
function localVar(name , valueType , defaultValue , propId) | |||
return cc.MemberVar:create(name , getVarType(valueType) , propId or -1 , defaultValue , false , 0); | |||
end | |||
local function classNewHook(tab , cls) | |||
if not cls or type(cls) ~= "userdata" then | |||
log(table.tostring(tab)) | |||
end | |||
log(type(cls)) | |||
local ret = newBindableArray(tab); | |||
rawset(ret , "NetVar" , cls); | |||
local onNew = cls.onNew; | |||
if onNew then | |||
onNew(cls , ret); | |||
end | |||
return ret; | |||
end | |||
local function classReadHook(tab , cls) | |||
local ret = newBindableArray(tab); | |||
rawset(ret , "NetVar" , cls); | |||
local onRead = cls.onRead; | |||
if onRead then | |||
onRead(cls , ret); | |||
end | |||
return ret; | |||
end | |||
local function classWriteHook(tab , cls) | |||
local onWrite = cls.onWrite; | |||
if onWrite then | |||
onWrite(cls , tab); | |||
end | |||
return rawget(tab , "Datas"); | |||
end | |||
-- 定义一个类 | |||
function defClass(name , ...) | |||
local arg = {...}; | |||
local cls = cc.NetClass:create(name); | |||
cls:setNewHookFunc(classNewHook); | |||
cls:setReadHookFunc(classReadHook); | |||
cls:setWriteHookFunc(classWriteHook); | |||
for i , v in ipairs(arg) do | |||
cls:addMemberVar(v) | |||
end | |||
if gNetClassType then | |||
print(string.format("the class named [%s] is exist",name)) | |||
end | |||
gNetClassType[name] = cls; | |||
local propByIds = {}; | |||
local propByNames = {}; | |||
-- 根据属性ID保存所有属性 | |||
for i , v in ipairs(arg) do | |||
propByIds[v:getPropId()] = v; | |||
propByNames[v:getName()] = v; | |||
end | |||
-- 根据属性ID获取属性名 | |||
function cls:getPropName(id) | |||
local prop = propByIds[id]; | |||
if prop then | |||
return prop:getName(); | |||
else | |||
return nil; | |||
end | |||
end | |||
-- 根据属性ID获取属性名 | |||
function cls:getPropId(name) | |||
local prop = propByNames[name]; | |||
if prop then | |||
return prop:getPropId(); | |||
else | |||
return nil; | |||
end | |||
end | |||
-- 根据属性ID设置一个值 | |||
function cls:set(object , id , value) | |||
object[self:getPropName(id)] = value; | |||
end | |||
-- 根据属性ID获取一个值 | |||
function cls:get(object , id) | |||
return object[self:getPropName(id)]; | |||
end | |||
-- 根据属性ID增加一个值 | |||
function cls:add(object , id , value) | |||
local name = self:getPropName(id); | |||
object[name] = object[name] + value; | |||
end | |||
cls:retain(); | |||
autoGC(cls); | |||
-- _G[name] = cls; | |||
return cls; | |||
end |
@@ -0,0 +1,209 @@ | |||
require("luaScript.Protocol.ProtoDef") | |||
local Protocol = class("Protocol" , require("luaScript.Protocol.BindableArray")) | |||
function Protocol:ctor(net) | |||
-- 协议对应的网络链接 | |||
self.net = net; | |||
-- 保存模块ID | |||
self.ModuleId = 99; | |||
-- 已经注册的服务器消息列表 | |||
self.PushMsgList = {} | |||
cc.GameObject.extend(self) | |||
self:addComponent(require("luaScript.cc.components.behavior.EventProtocol"):new()):exportMethods() | |||
end | |||
-- 记录所有发送消息等待回调的函数列表,当断线重连时 | |||
g_regMsgCallBackFuncs = {} | |||
--[[ | |||
发送消息,并接收回调 | |||
args = { | |||
cmd , -- 命令ID | |||
sender , -- 可选参数,发送的结构体实例(通过defClass定义的类的new创建出来的实例) | |||
reader , -- 可选参数,接收的结构体类型(通过defClass定义) | |||
func , -- 可选参数,回调函数,类型是func(statusCode , response),其中response时read结构体读出来的数据 | |||
} | |||
--]] | |||
function Protocol:sendResponse(args) | |||
assert(args.cmd ~= nil); | |||
-- 检查一下网络是否正常 | |||
if not self.net or not self.net:isConnected() then | |||
if isWin32Platform() then | |||
assert(false); | |||
end | |||
return | |||
end | |||
-- 如果定义了需要发送的数据,就发送数据,否则只发命令 | |||
if args.sender then | |||
args.sender:send(self.ModuleId , args.cmd, self.net); | |||
else | |||
self.net:sendCmd(self.ModuleId , args.cmd); | |||
end | |||
local unregFunc = nil | |||
local function onMsg(statusCode , stream) | |||
-- 清空注册以及清空记录 | |||
g_regMsgCallBackFuncs[unregFunc]() | |||
g_regMsgCallBackFuncs[unregFunc] = nil | |||
if statusCode ~= 0 then | |||
args.func(statusCode); | |||
print("onMsg时返回了非0 statusCode:" .. tostring(statusCode)); | |||
return | |||
end | |||
if args.reader then | |||
local response = args.reader:tryRead(stream); | |||
if response then | |||
args.func(statusCode , response); | |||
else | |||
args.func(2); | |||
end | |||
else | |||
args.func(statusCode); | |||
end | |||
end | |||
-- 如果定义了回调函数,则接收数据 | |||
if args.func and args.resCmd then | |||
assert(type(args.func) == "function") | |||
self.net:regMsg(self.ModuleId, args.resCmd, onMsg); | |||
unregFunc = function()self.net:unregMsg(onMsg)end | |||
g_regMsgCallBackFuncs[unregFunc] = unregFunc | |||
end | |||
end | |||
--[[ | |||
定义网络消息函数,并把这个函数导出到当前Protocol类中对外公开 | |||
对外公开的函数定义是name(sendArgs , responseFunc)或name(responseFunc) | |||
args = { | |||
name , -- 需要导出的函数名称 | |||
cmd , -- 命令ID | |||
sender , -- 可选参数,发送的结构体类型(通过defClass定义) | |||
reader , -- 可选参数,接收的结构体类型(通过defClass定义) | |||
func , -- 可选参数,回调函数,类型是func(statusCode , response)或func(statusCode),其中response时read结构体读出来的数据 | |||
} | |||
--]] | |||
function Protocol:defMsgFunc(args) | |||
--[[ | |||
{ | |||
name = "", | |||
cmd = number, | |||
resCmd = number, | |||
sender = netClass, | |||
reader = netClass, | |||
func = function, | |||
} | |||
]] | |||
assert(args.name ~= nil and type(args.cmd) == "number"); | |||
if args.sender then | |||
-- sendArgs是一个表,会把这个表的数据拷贝到sender中 | |||
local function sendData(self , sendArgs , responseFunc) | |||
local args = clone(args); | |||
local sender = args.sender:new(); | |||
for i , v in pairs(sendArgs) do | |||
sender[i] = v; | |||
end | |||
args.sender = sender; | |||
local argFunc = args.func; | |||
if argFunc then | |||
args.func = function(statusCode , response) | |||
argFunc(statusCode , response); | |||
if responseFunc then | |||
responseFunc(statusCode , response) | |||
end | |||
end; | |||
elseif responseFunc then | |||
args.func = responseFunc; | |||
end | |||
self:sendResponse(args); | |||
end | |||
self[args.name] = sendData; | |||
else | |||
local function sendData(self , responseFunc) | |||
local args = clone(args); | |||
local argFunc = args.func; | |||
if argFunc then | |||
args.func = function(statusCode , response) | |||
argFunc(statusCode , response); | |||
if responseFunc then | |||
responseFunc(statusCode , response) | |||
end | |||
end; | |||
elseif responseFunc then | |||
args.func = responseFunc; | |||
end | |||
self:sendResponse(args); | |||
end | |||
self[args.name] = sendData; | |||
end | |||
end | |||
--[[ | |||
定义一个推送消息,会持续地接收这个消息,并通过回调函数返回数据 | |||
args = { | |||
cmd , -- 命令ID | |||
reader , -- 可选参数,接收的结构体类型(通过defClass定义) | |||
func , -- 可选参数,回调函数,类型是func(statusCode , response),其中response时read结构体读出来的数据 | |||
} | |||
--]] | |||
function Protocol:defPushMsg(args) | |||
assert(args.cmd ~= nil); | |||
local function onMsg(statusCode , stream) | |||
if statusCode ~= 0 then | |||
args.func(statusCode); | |||
print("onMsg时返回了非0 statusCode:" .. tostring(statusCode)); | |||
return | |||
end | |||
if args.reader then | |||
local response = args.reader:tryRead(stream); | |||
if response then | |||
args.func(statusCode , response); | |||
else | |||
args.func(2); | |||
end | |||
else | |||
args.func(statusCode); | |||
end | |||
end | |||
-- 如果定义了回调函数,则接收数据 | |||
if args.func then | |||
--table.insert(args.cmd, args.func); | |||
self.PushMsgList[args.cmd] = onMsg--args.func | |||
self.net:regMsg(self.ModuleId, args.cmd, onMsg); | |||
end | |||
end | |||
function Protocol:defPullMsg(args) | |||
if args.sender then | |||
-- sendArgs是一个表,会把这个表的数据拷贝到sender中 | |||
local function sendData(responseFunc) | |||
local args = clone(args); | |||
local sender = args.sender:new(); | |||
args.sender = sender; | |||
args.func = responseFunc; | |||
self:sendResponse(args); | |||
end | |||
else | |||
local function sendData(responseFunc) | |||
local args = clone(args); | |||
args.func = responseFunc; | |||
self:sendResponse(args); | |||
end | |||
end | |||
self:defMsgFunc(args); | |||
end | |||
function Protocol:unRegAll() | |||
for cmdId,func in pairs(self.PushMsgList) do | |||
self.net:unregMsg(func); | |||
end | |||
end | |||
return Protocol; |
@@ -0,0 +1,426 @@ | |||
-- PHP文档地址,用户名:dd 密码:ddtech | |||
-- http://120.76.238.236:8999/wiki/index.php?title=%E9%A6%96%E9%A1%B5 | |||
local ProtocolClubZhanji = class("ProtocolClubZhanji", require("luaScript.Protocol.ProtocolZhanJi")) | |||
local InterfaceKey = | |||
{ | |||
idx = "gamb.gidx", -- 茶馆战绩新接口 | |||
PHP_CLUB_ZHANJI_CONSUME = "group.getGroupDateStat",--茶馆请求战绩消耗 | |||
} | |||
function ProtocolClubZhanji:ctor() | |||
ProtocolClubZhanji.super.ctor(self); | |||
self.fileName = "ZhanJi_Club" | |||
--[[ | |||
self.zhanJiIdxs = | |||
{ | |||
[clubid] = | |||
{ | |||
[usertype] = | |||
{ | |||
tpage = 18, | |||
infos = | |||
{ | |||
[page] = {idx, idx, idx, idx, ...}, | |||
[page] = {idx, idx, idx, idx, ...}, | |||
... | |||
} | |||
}, | |||
... | |||
}, | |||
... | |||
}, | |||
... | |||
--]] | |||
self.zhanJiIdxs = {} | |||
self.zhanJiIdxStatus = {} | |||
self.zhanJiIdxLocals = {} | |||
-- 当前显示的战绩的总页数 | |||
self.tpage = 0 | |||
--大赢家详情数据 | |||
self.dayijingjiadetail = nil | |||
self.shareUrl = "http://m.xiaopengol.com/replay.php" --分享战绩链接 | |||
self:loadFromFile(); | |||
end | |||
-- 初始化 | |||
function ProtocolClubZhanji:init() | |||
end | |||
-- 获取指定的战绩信息列表 | |||
-- clubId:茶馆ID | |||
-- usertype:用户类型 | |||
-- page:页数 | |||
function ProtocolClubZhanji:getZhanJiList(clubId, usertype, page) | |||
-- 首先找到对应的 idx_list | |||
local zhanjiInfoList = app.club_zhanji.zhanjiInfoList; | |||
if not zhanjiInfoList then | |||
return | |||
end | |||
if not self.zhanJiIdxs[clubId] | |||
or not self.zhanJiIdxs[clubId][usertype] | |||
or not self.zhanJiIdxs[clubId][usertype]["infos"] | |||
or not self.zhanJiIdxs[clubId][usertype]["infos"][page] then | |||
return {} | |||
end | |||
local zhanjiList = {} | |||
local idx_list = self.zhanJiIdxs[clubId][usertype]["infos"][page] | |||
local index = 10000--保持原有顺序,这里用递减 | |||
for _,pid in pairs(idx_list) do | |||
if self.zhanjiInfoList[pid] and self.zhanjiInfoList[pid].hide ~= 1 then | |||
index = index - 1 | |||
local endtime = tostring(index) | |||
zhanjiList[endtime] = self.zhanjiInfoList[pid] | |||
end | |||
end | |||
return zhanjiList; | |||
end | |||
--请求战绩的编号列表 | |||
-- 通过ID查找指定ID玩家的战绩 | |||
function ProtocolClubZhanji:getIdxlistByPlayerUid(clubId, userType, time, page,suid,isSearch) | |||
local tt = | |||
{ | |||
action = InterfaceKey.idx; | |||
app = getAppId(); --应用id | |||
uid = app.user.loginInfo.uid; --用户id | |||
suid = suid; --需要查询的战绩的玩家ID | |||
gid = clubId; --茶馆ID | |||
date = time; --格式:"2018-02-02" 获取时间,如传空则获取当天 | |||
type = userType; --1管理員查詢,2玩家查詢 | |||
page = page or 1; --是否是新版(针对新版有两种游戏战绩的情况) | |||
}; | |||
log("ProtocolClubZhanji:getIdxlist", table.tostring(tt)) | |||
httpPost(self.phpUrl, tt, function(status, response) | |||
self:getIdxlistResponse(status, response, clubId, userType,isSearch) | |||
end) | |||
end | |||
--请求战绩的编号列表 | |||
-- 茶馆的战绩分不同茶馆的不同类型的战绩,所以在这里单独保存ID,无需存文件 | |||
function ProtocolClubZhanji:getIdxlist(clubId, userType, time, page) | |||
local tt = | |||
{ | |||
action = InterfaceKey.idx; | |||
app = getAppId(); --应用id | |||
uid = app.user.loginInfo.uid; --用户id | |||
gid = clubId; --茶馆ID | |||
date = time; --格式:"2018-02-02" 获取时间,如传空则获取当天 | |||
type = userType; --1管理員查詢,2玩家查詢 | |||
page = page or 1; --是否是新版(针对新版有两种游戏战绩的情况) | |||
}; | |||
log("ProtocolClubZhanji:getIdxlist", table.tostring(tt)) | |||
httpPost(self.phpUrl, tt, function(status, response) | |||
self:getIdxlistResponse(status, response, clubId, userType) | |||
end) | |||
end | |||
-- 获取战绩ID列表的回复 | |||
-- 并和本地数据进行比较,找出本地未下载的部分进行下载 | |||
function ProtocolClubZhanji:getIdxlistResponse(status, response, clubId, userType,isSearch) | |||
logD("ProtocolClubZhanji:getIdxlistResponse()", status, response) | |||
local ret, ttResult = checkPhpResponse(status, response) | |||
if not ret then | |||
logE("ProtocolClubZhanji:getIdxlistResponse()", tostring(ttResult)) | |||
local ttResposne = json.decode(response) | |||
if ttResposne and type(ttResposne) == "table" and ttResposne.error then | |||
showTooltip(ttResposne.error) | |||
end | |||
return | |||
end | |||
if ret and table.nums(ttResult.idx) == 0 and isSearch then | |||
showTooltip("该玩家暂无战绩") | |||
end | |||
-- 保存页数对应的idx | |||
local page = ttResult.page | |||
local tpage = ttResult.tpage | |||
self.tpage = tpage; | |||
-- 茶馆 | |||
if not self.zhanJiIdxs[clubId] then | |||
self.zhanJiIdxs[clubId] = {} | |||
end | |||
-- 用户类型 | |||
if not self.zhanJiIdxs[clubId][userType] then | |||
self.zhanJiIdxs[clubId][userType] = {} | |||
end | |||
-- 页数 | |||
self.zhanJiIdxs[clubId][userType].tpage = tonumber(tpage) | |||
if not self.zhanJiIdxs[clubId][userType].infos then | |||
self.zhanJiIdxs[clubId][userType].infos = {} | |||
end | |||
local idxs = {} | |||
for k,pid in pairs(ttResult.idx) do | |||
table.insert(idxs, pid) | |||
end | |||
self.zhanJiIdxs[clubId][userType]["infos"][page] = idxs; | |||
--确认状态 | |||
for pid,v in pairs(ttResult.idxStatus) do | |||
self.zhanJiIdxStatus[pid] = v.status | |||
self.zhanJiIdxLocals[pid] = v.locals | |||
-- table.insert(idxs, pid) | |||
end | |||
if ttResult.url and ttResult.url~="" then | |||
self.shareUrl = ttResult.url | |||
end | |||
-- 比较没有的战绩并下载 | |||
self:checkAndDownload(ttResult.idx); | |||
end | |||
--请求战绩的消耗 | |||
function ProtocolClubZhanji:requestZhanjiConsume(gID, time) | |||
local tt = | |||
{ | |||
action = "group.getGroupDateStat"; --接口 | |||
uid = app.user.loginInfo.uid; --群用户id | |||
app = getAppId(); --应用id | |||
gid = gID; --群id | |||
date = time; --日期 | |||
}; | |||
logD("ProtocolClubZhanji:requestZhanjiConsume()", table.tostring(tt)) | |||
httpPost(self.phpUrl, tt, handler(self, self.onZhanjiConsumeResponse)) | |||
end | |||
function ProtocolClubZhanji:onZhanjiConsumeResponse(status, response) | |||
logD("ProtocolClubZhanji:onZhanjiConsumeResponse()", tostring(status), table.tostring(response)) | |||
if status ~= "successed" then | |||
-- showTooltip("获取消耗数据失败,链接失败") | |||
return | |||
end | |||
--do return end | |||
local ttResponse = json.decode(response) | |||
if not ttResponse or type(ttResponse) ~= "table" then | |||
-- showTooltip("获取消耗数据失败,数据为空") | |||
return | |||
end | |||
self.ZhanjiXiaohao = {}; | |||
if ttResponse.code == 200 and ttResponse.result and type(ttResponse.result) == "table" then | |||
local roomNum = ttResponse.result.openhouse_count; --成局数 | |||
local cardCost = ttResponse.result.card_consume_count; --房卡消耗 | |||
local activityCardCost = ttResponse.result.owner_props_card_count; --活动房卡消耗 | |||
local costCardCount = ttResponse.result.owner_openhouse_count; --扣卡局数 | |||
local notCostCardCount = ttResponse.result.owner_unconsume_count; --未扣卡局数 | |||
local propList = ttResponse.result.propList; -- 专用钻石消耗明细 | |||
app:dispatchEvent({name = "ClubZhanjiConsumeCallback", roomNum = roomNum, cardCost = cardCost, activityCardCost = activityCardCost, | |||
costCardCount = costCardCount,notCostCardCount = notCostCardCount, propList = propList}); | |||
end | |||
end | |||
--请求战绩确认 | |||
function ProtocolClubZhanji:requestZhanjiSure(gID,idx ,callback) | |||
local phpAddress = getGlobalPhpUrl() | |||
local tt = {}; | |||
tt.action = "group.setupRoomlog"; | |||
tt.uid = app.user.loginInfo.uid;--设置人 | |||
tt.app = getAppId(); --应用id | |||
tt.gid = gID; --茶馆ID | |||
tt.gamb_id = idx --战绩标示 | |||
tt.type = 1 --1茶馆状态确认 | |||
logD("ProtocolClubZhanji:requestZhanjiSure()", table.tostring(tt)) | |||
httpPost(phpAddress, tt, function(status, response) | |||
logD("ProtocolClubZhanji:requestZhanjiSure() response", response) | |||
local clubResponse = json.decode(response) | |||
if type(clubResponse) ~= "table" then | |||
showPHPFailedResult("请求战绩确认 response type is not table") | |||
return | |||
end | |||
logD("ProtocolClubZhanji:requestZhanjiSure() response", table.tostring(clubResponse)) | |||
-- self.zhanjiTongjiDataList = {}; | |||
local result = clubResponse.result | |||
if clubResponse.code == 200 then | |||
self.zhanJiIdxStatus[result.gamb_id] = result.status | |||
if callback then callback() end | |||
-- app:dispatchEvent({name = "ClubZhanjiSureCallback", result = result}); | |||
elseif clubResponse.code == 1052 then --已经确认过了 | |||
self.zhanJiIdxStatus[idx] = 2 | |||
if callback then callback() end | |||
else | |||
showConfirmDialog(clubResponse.error) | |||
end | |||
end) | |||
end | |||
--获取战绩统计数据 | |||
function ProtocolClubZhanji:requestZhanjiGroupDateList(gID, startdate, enddate) | |||
local phpAddress = getGlobalPhpUrl() | |||
local tt = {}; | |||
tt.action = "group.getGroupDateStatList"; | |||
tt.uid = app.user.loginInfo.uid;--设置人 | |||
tt.app = getAppId(); --应用id | |||
tt.gid = gID; --茶馆ID | |||
tt.startdate = startdate; --不传参数默认最近一周 | |||
tt.enddate = enddate; --不传参数默认当天日期 | |||
tt.version="20190122" | |||
log("ProtocolClubZhanji:requestZhanjiGroupDateList_send", table.tostring(tt)) | |||
app.waitDialogManager:showWaitNetworkDialog("连接中..."); | |||
httpPost(phpAddress, tt, function(status, response) | |||
app.waitDialogManager:closeWaitNetworkDialog(); | |||
log("ProtocolClubZhanji:requestZhanjiGroupDateList", table.tostring(response)) | |||
local clubResponse = json.decode(response) | |||
if type(clubResponse) ~= "table" then | |||
showPHPFailedResult("获取战绩统计数据 response type is not table") | |||
return | |||
end | |||
self.zhanjiTongjiDataList = {}; | |||
local result = clubResponse.result | |||
if clubResponse.code == 200 then | |||
if result.list and table.nums(result.list) > 0 then | |||
local tTongjiList = {}; | |||
-- local idx = 1 | |||
for date,list in pairs(result.list) do | |||
local zhanjiTongjiDataList = {} | |||
-- for _,list | |||
local zhanjiTongjiData = {} | |||
zhanjiTongjiData.create_date = date | |||
zhanjiTongjiData.openhouse_count = 0 | |||
zhanjiTongjiData.owner_card_consume_count = 0 | |||
zhanjiTongjiData.owner_props_card_count = 0 | |||
zhanjiTongjiData.play_win_number = 0 | |||
zhanjiTongjiData.cost_card_count = 0--扣卡局 | |||
zhanjiTongjiData.not_cost_card_count = 0--未扣卡局 | |||
for _,v in pairs(list) do | |||
-- zhanjiTongjiData.create_date = zhanjiTongjiData.create_date + v.create_date;--日期 | |||
zhanjiTongjiData.openhouse_count = zhanjiTongjiData.openhouse_count + v.openhouse_count;--开房成局 | |||
zhanjiTongjiData.owner_card_consume_count = zhanjiTongjiData.owner_card_consume_count + v.owner_card_consume_count;--群主消耗 | |||
zhanjiTongjiData.owner_props_card_count = zhanjiTongjiData.owner_props_card_count + v.owner_props_card_count;--群主专属房卡/房卡消耗 | |||
--新加 | |||
zhanjiTongjiData.cost_card_count = zhanjiTongjiData.cost_card_count + v.owner_openhouse_count;--扣卡局 | |||
zhanjiTongjiData.not_cost_card_count = zhanjiTongjiData.not_cost_card_count + v.owner_unconsume_count;--未扣卡局 | |||
end | |||
zhanjiTongjiData.list = list | |||
if result.extlist and result.extlist[date] then | |||
zhanjiTongjiData.play_win_number = result.extlist[date].play_win_number or 0 | |||
end | |||
tTongjiList[date] = zhanjiTongjiData | |||
-- idx = idx + 1 | |||
end | |||
self.zhanjiTongjiDataList[tonumber(gID)] = tTongjiList; | |||
end | |||
self:dispatchEvent({name = "onGetZhanjiGroupDateListSucc"}); | |||
elseif clubResponse.code == 1020 then | |||
showConfirmDialog("获取战绩统计数据,参数错误 code = "..clubResponse.code) | |||
elseif clubResponse.code == 1026 then | |||
showConfirmDialog("获取战绩统计数据,非管理员操作 code = "..clubResponse.code); | |||
elseif clubResponse.code == 1014 then | |||
showConfirmDialog(PLN.CLUB_ZHANJI_ERR_1104..clubResponse.code); | |||
else | |||
showConfirmDialog("获取战绩统计数据 code = "..clubResponse.code) | |||
end | |||
end) | |||
end | |||
--请求大赢家明细 | |||
function ProtocolClubZhanji:requestDaYingJiaZhanJi(gID, suid,lastday) | |||
local tt = | |||
{ | |||
action = "group.winlog"; --接口 | |||
uid = app.user.loginInfo.uid; --群用户id | |||
app = getAppId(); --应用id | |||
gid = gID; --群id | |||
suid = suid; | |||
lastday = lastday; | |||
}; | |||
logD("ProtocolClubZhanji:requestDaYingJiaZhanJi()", table.tostring(tt)) | |||
httpPost(self.phpUrl, tt, handler(self, self.onDaYingJiaZhanJiresponse)) | |||
app.waitDialogManager:showWaitNetworkDialog(); | |||
end | |||
function ProtocolClubZhanji:onDaYingJiaZhanJiresponse(status, response) | |||
logD("ProtocolClubZhanji:onDaYingJiaZhanJiresponse()", tostring(status), table.tostring(response)) | |||
app.waitDialogManager:closeWaitNetworkDialog(); | |||
if status ~= "successed" then | |||
showTooltip("获取大赢家数据列表失败") | |||
return | |||
end | |||
--do return end | |||
local ttResponse = json.decode(response) | |||
if not ttResponse or type(ttResponse) ~= "table" then | |||
showTooltip("获取大赢家数据列表失败,数据为空") | |||
return | |||
end | |||
self.dayijingjiadetail = ttResponse.result | |||
--确认状态 | |||
for k,v in pairs(self.dayijingjiadetail.list) do | |||
local pid = v.gambid | |||
self.zhanJiIdxStatus[pid] = v.status | |||
end | |||
app:dispatchEvent({name = "onDaYingJiaZhanJiresponse"}) | |||
end | |||
--- ProtocolClubZhanji:requestDeleteZhanJi 请求删除战绩 | |||
-- @param gID 群id | |||
-- @param zhangjiid 战绩id | |||
-- @param optype 操作类型 | |||
function ProtocolClubZhanji:requestDeleteZhanJi(gID, zhangjiid, optype) | |||
optype = optype or 1 | |||
local tt = | |||
{ | |||
action = "group.setupRoomlog"; --接口 | |||
uid = app.user.loginInfo.uid; --群用户id | |||
app = getAppId(); --应用id | |||
gid = gID; --群id | |||
gamb_id = zhangjiid; | |||
type = 2; | |||
value = optype | |||
}; | |||
app.waitDialogManager:showWaitNetworkDialog(); | |||
logD("ProtocolClubZhanji:requestDeleteZhanJi()", table.tostring(tt)) | |||
httpPost(self.phpUrl, tt, function(status, response) | |||
app.waitDialogManager:closeWaitNetworkDialog(); | |||
if status ~= "successed" then | |||
showTooltip("操作失败") | |||
return | |||
end | |||
local ttResponse = json.decode(response) | |||
if not ttResponse or type(ttResponse) ~= "table" or ttResponse.code ~= 200 then | |||
showTooltip(ttResponse.error) | |||
return | |||
end | |||
showTooltip("删除成功") | |||
local pid = ttResponse.result.gamb_id | |||
self.zhanjiInfoList[pid].hide = ttResponse.result.hide | |||
self:dispatchEvent({name = "onDeleteZhanJiResponse"}) | |||
end) | |||
end | |||
return ProtocolClubZhanji |
@@ -0,0 +1,39 @@ | |||
require("luaScript.Protocol.ProtoDef") | |||
BoolPacket = defClass("BoolPacket" | |||
, defVar("boolValue", VT_Bool, false) | |||
) | |||
BytePacket = defClass("BytePacket" | |||
, defVar("byteValue", VT_UChar, 0) | |||
) | |||
ShortPacket = defClass("ShortPacket" | |||
, defVar("shortValue", VT_Short, 0) | |||
) | |||
IntPacket = defClass("IntPacket" | |||
, defVar("intValue", VT_Int, 0) | |||
) | |||
LongPacket = defClass("LongPacket" | |||
, defVar("longValue", VT_Long, 0) | |||
) | |||
StringPacket = defClass("StringPacket" | |||
, defVar("stringValue", VT_String, "") | |||
) | |||
IntListPacket = defClass("IntListPacket" | |||
, defVar("intList", VT_Vector(VT_Int)) | |||
) | |||
LongListPacket = defClass("LongListPacket" | |||
, defVar("longList", VT_Vector(VT_Long)) | |||
) | |||
RemainTimePacket = defClass("RemainTimePacket" | |||
, defVar("remainTime", VT_RemainTime(VT_LLong, 1), 0) | |||
) | |||
@@ -0,0 +1,267 @@ | |||
--[[ | |||
子游戏列表 | |||
服务器下发的游戏图标,会带有该文件的时间戳, | |||
每次获取到游戏列表都检查本地文件的时间戳和服务器的时间戳,如果不一致,说明需要更新图标 | |||
GameInfo = | |||
{ | |||
-- 基本信息 | |||
gameId = 8, | |||
gameName = "斗地主", | |||
gameIcon = "http://www.dingdingqipai.com/doudizhu.png?v=1008987887" | |||
gameRule = "", | |||
sortIndex = 9, | |||
--子游戏图标在本地的文件名 | |||
iconPath = "doudizhu.png", | |||
iconType = "loc" -- "loc" 表示游戏自带,"net"表示从网络下载 | |||
-- 版本信息 | |||
version = "1003", | |||
versionUrls = | |||
{ | |||
[1] = "http://192.168.3.14/www/liuhuqiang/1003/", | |||
[2] = "http://192.168.3.14/www/liuhuqiang/1003/", | |||
} | |||
} | |||
-- 本地文件记录每个游戏的游戏图标的时间戳 | |||
GameIconTimes = | |||
{ | |||
[1] = "23840280312", | |||
[2] = "23840280312", | |||
} | |||
-- 本地文件记录每个游戏的最新版本号 | |||
GameVersions = | |||
{ | |||
[1] = "1001", | |||
[2] = "1001", | |||
[3] = "1001", | |||
} | |||
--]] | |||
local ProtocolGameList = class("ProtocolGameList") | |||
function ProtocolGameList:ctor() | |||
cc.GameObject.extend(self) | |||
self:addComponent(require("luaScript.cc.components.behavior.EventProtocol"):new()):exportMethods() | |||
self.phpUrl = getGlobalPhpUrl() | |||
-- 游戏列表 | |||
self.gameList = {} | |||
-- 图标的时间戳 | |||
self.GameIconTimesKey = "GameIconTimes" | |||
self.GameIconTimes = {} | |||
-- 游戏的版本号 | |||
self.GameVersionsKey = "GameVersions" | |||
self.GameVersions = {} | |||
-- 初始化进度 | |||
self.initStep = 0 | |||
self.initSuccessed = false; | |||
self:loadGameVersionsInfo() | |||
self:loadGameIconTimesInfo() | |||
end | |||
-- 初始化子游戏列表 | |||
function ProtocolGameList:initGameList() | |||
local params = | |||
{ | |||
action = "system.gameinfo", | |||
app = getAppId(), | |||
uid = loadUserId(), | |||
} | |||
logD("ProtocolGameList:initGameList() ", table.tostring(params)); | |||
httpPost(self.phpUrl, params, handler(self, self.onGameListResponse)) | |||
end | |||
-- 收到服务器下发的游戏列表信息 | |||
function ProtocolGameList:onGameListResponse(status, response) | |||
if status ~= "successed" then | |||
return | |||
end | |||
if not response then | |||
return | |||
end | |||
logD("ProtocolGameList:onGameListResponse() ", response); | |||
local jsonRet = json.decode(response) | |||
if not jsonRet then | |||
return | |||
end | |||
logD("ProtocolGameList:onGameListResponse() ", table.tostring(jsonRet)); | |||
if tonumber(jsonRet.code) ~= 200 then | |||
return | |||
end | |||
if not jsonRet.result or type(jsonRet.result) ~= "table" then | |||
return | |||
end | |||
for k,v in pairs(jsonRet.result) do | |||
local gameInfo = self.gameList[tonumber(k)] or {} | |||
gameInfo.gameId = tonumber(k) | |||
gameInfo.gameName = tostring(v.name) | |||
gameInfo.gameIcon = tostring(v.icon) | |||
gameInfo.gameRule = tostring(v.gamecfg) | |||
gameInfo.sortIndex = tonumber(v.sort) | |||
self.gameList[tonumber(k)] = gameInfo; | |||
end | |||
self:downloadAllIcon() | |||
-- 通知初始化完成 | |||
self:onInitFinished() | |||
end | |||
-- 初始化子游戏的版本信息 | |||
function ProtocolGameList:initGameVersions() | |||
local params = | |||
{ | |||
action = "system.games", | |||
app = getAppId(), | |||
uid = loadUserId(), | |||
apkVer = getAppVersion(), | |||
installGameVer = "", | |||
} | |||
logD("ProtocolGameList:initGameVersions() ", table.tostring(params)); | |||
httpPost(self.phpUrl, params, handler(self, self.onGameVersionsResponse)) | |||
end | |||
-- 收到服务器下发的游戏版本信息 | |||
function ProtocolGameList:onGameVersionsResponse(status, response) | |||
if status ~= "successed" then | |||
return | |||
end | |||
if not response then | |||
return | |||
end | |||
logD("ProtocolGameList:onGameVersionsResponse() ", response); | |||
local jsonRet = json.decode(response) | |||
if not jsonRet then | |||
return | |||
end | |||
logD("ProtocolGameList:onGameVersionsResponse() ", table.tostring(jsonRet)); | |||
if tonumber(jsonRet.code) ~= 200 then | |||
return | |||
end | |||
--[[ | |||
version = "1003", | |||
versionUrls = | |||
{ | |||
[1] = "http://192.168.3.14/www/liuhuqiang/1003/", | |||
[2] = "http://192.168.3.14/www/liuhuqiang/1003/", | |||
} | |||
--]] | |||
if not jsonRet.result or type(jsonRet.result) ~= "table" then | |||
return | |||
end | |||
for k,v in pairs(jsonRet.result) do | |||
local gameInfo = self.gameList[tonumber(k)] or {} | |||
gameInfo.version = tostring(v.ver) | |||
if v.url and v.url ~= "" then | |||
gameInfo.versionUrls = toStringArray(",")(v.url) | |||
end | |||
self.gameList[tonumber(k)] = gameInfo; | |||
end | |||
-- 通知初始化完成 | |||
self:onInitFinished() | |||
end | |||
-- 初始化完成后发送事件 | |||
function ProtocolGameList:onInitFinished() | |||
self.initStep = self.initStep + 1 | |||
if self.initStep >= 2 then | |||
self.initSuccessed = true; | |||
self:dispatchEvent({name = "onInitFinished"}) | |||
end | |||
end | |||
-- 下载所有游戏的游戏图标 | |||
function ProtocolGameList:downloadAllIcon() | |||
for k,v in pairs(self.gameList) do | |||
if v.gameIcon and v.gameIcon ~= "" then | |||
local iconUrl, iconTimeNew = convertIconUrl(v.gameIcon) | |||
local iconTimeOld = self:getGameIconTime(k) | |||
local pngName = getImageNameFromUrl(iconUrl) | |||
local gameInfo = self.gameList[tonumber(k)] | |||
if gameInfo then | |||
gameInfo.iconPath = pngName | |||
gameInfo.iconType = "net" | |||
end | |||
if tonumber(iconTimeNew) > tonumber(iconTimeOld) then | |||
getImageFromUrlWithTime(iconUrl, pngName, nil, function() | |||
self:dispatchEvent({name="downGameIconSuccessed", gameId = k}) | |||
self:updateGameIconTime(k, iconTimeNew) | |||
end) | |||
end | |||
end | |||
end | |||
end | |||
-- 读取本地记录的游戏图标的时间戳 | |||
function ProtocolGameList:loadGameIconTimesInfo() | |||
local value = loadUserInfo(self.GameIconTimesKey) | |||
self.GameIconTimes = json.decode(value) or {} | |||
end | |||
-- 保存游戏图标的时间戳到本地 | |||
function ProtocolGameList:saveGameIconTimesInfo() | |||
local value = json.encode(self.GameIconTimes) | |||
saveUserInfo(self.GameIconTimesKey, value) | |||
end | |||
-- 获取指定游戏的图标时间戳 | |||
function ProtocolGameList:getGameIconTime(gameId) | |||
return self.GameIconTimes[tostring(gameId)] or 0 | |||
end | |||
-- 更新指定游戏的图标时间戳 | |||
function ProtocolGameList:updateGameIconTime(gameId, timeNew) | |||
self.GameIconTimes[tostring(gameId)] = timeNew or 0; | |||
self:saveGameIconTimesInfo() | |||
end | |||
-- 读取本地记录的游戏的资源版本号 | |||
function ProtocolGameList:loadGameVersionsInfo() | |||
local value = loadUserInfo(self.GameVersionsKey) | |||
self.GameVersions = json.decode(value) or {} | |||
end | |||
-- 保存游戏的资源版本号到本地 | |||
function ProtocolGameList:saveGameVersionsInfo() | |||
local value = json.encode(self.GameVersions) | |||
saveUserInfo(self.GameVersionsKey, value) | |||
end | |||
-- 获取指定游戏的图标时间戳 | |||
function ProtocolGameList:getGameVersion(gameId) | |||
return self.GameVersions[tostring(gameId)] or "0000" | |||
end | |||
-- 更新指定游戏的资源版本号 | |||
function ProtocolGameList:updateGameVersion(gameId, versionNew) | |||
self.GameVersions[tostring(gameId)] = versionNew or "0000"; | |||
self:saveGameIconTimesInfo() | |||
end | |||
-- 更新子游戏的配置信息 | |||
-- 部分子游戏的配置是GameServer下发的,也需要保存在这里 | |||
function ProtocolGameList:updateGameRuleString(gameId, gameRule) | |||
local gameInfo = self.gameList[tonumber(gameId)] or {} | |||
gameInfo.gameId = tonumber(gameId) | |||
gameInfo.gameRule = tostring(gameRule) | |||
self.gameList[tonumber(gameId)] = gameInfo; | |||
end | |||
-- 更新子游戏的配置信息,返回一个jsonString | |||
function ProtocolGameList:getGameRuleString(gameId) | |||
return self.gameList[tonumber(gameId)] | |||
end | |||
return ProtocolGameList; |
@@ -0,0 +1,697 @@ | |||
require("luaScript.Protocol.ProtocolCommon") | |||
local Hall = class("Hall" , require("luaScript.Protocol.Protocol")) | |||
--[[ | |||
请求 0x0114 : | |||
请求创建房间 | |||
│ | |||
┌───────────────┴────────────┒ | |||
│ │ | |||
回复 0x0116 : 回复 0x0117 | |||
返回创建结果 已经在房间里面了 | |||
│ | |||
│ | |||
请求:0x0115 请求 0x0118 | |||
请求进入房间 请求回到房间 | |||
]] | |||
-- 命令集合 | |||
local HallCmd = { | |||
--[[/** | |||
* 用户创建房间 | |||
* <pre> | |||
* 请求: {@code CreateRoomRequest} | |||
* 返回:- 创建成功返回 0x0116 | |||
* 返回:- 若此时用户已经在房间里面玩牌,则返回 0x0117 | |||
* </pre> | |||
*/--]] | |||
CreateRoomRequest = 0x0114, | |||
--[[/** | |||
* 申请加入私人房 | |||
* <pre> | |||
* 请求: {@code JoinRoomRequest} | |||
* 返回:- 加入成功返回 0x0118 | |||
* </pre> | |||
*/--]] | |||
JoinRoomRequest = 0x0115, | |||
--[[/** | |||
* 创建房间返回结果 | |||
* <pre> | |||
* 推送: {@code CreateRoomResponse} | |||
* </pre> | |||
*/--]] | |||
CreateRoomResponse = 0x0116, | |||
--[[/** | |||
* 创建房间时用户已经在桌子上玩牌,此时客户端通过0x8001消息来重新进入游戏 | |||
* <pre> | |||
* 推送: {@code CreateRoomResponseIn} | |||
* </pre> | |||
*/--]] | |||
CreateRoomResponseIn = 0x0117, | |||
--[[/** | |||
* 申请加入私人房返回结果 | |||
* <pre> | |||
* 推送: {@code CreateRoomResponse} | |||
* </pre> | |||
*/--]] | |||
JoinRoomResponse = 0x0118, | |||
--[[/** | |||
* 房间列表请求 | |||
* <pre> | |||
* 推送: {@code getRoomListRequest} | |||
* </pre> | |||
*/--]] | |||
getRoomListRequest = 0x4001, | |||
--[[/** | |||
* 房间列表返回 | |||
* <pre> | |||
* 推送: {@code getRoomListResponse} | |||
* </pre> | |||
*/--]] | |||
getRoomListResponse = 0x4002, | |||
--[[/** | |||
* 快速加入 | |||
* <pre> | |||
* 推送: {@code FastJoinRoomlyRequest} | |||
* </pre> | |||
*/--]] | |||
FastJoinRoomlyRequest = 0x011a, | |||
--[[/** | |||
* 玩家已经在房间里面了,则发送此消息请求进入房间 | |||
* <pre> | |||
* 推送: {@code EnterRoomRequest} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_ENTER_ROOM = 0x8001, | |||
--[[/** | |||
* 客户端通过0x8001协议进入房间时, 优先通知客户端桌子游戏信息 | |||
* <pre> | |||
* 推送: {@code EnterRoomResponse} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_ENTER_ROOM_RESPONSE = 0x8017, | |||
--[[/** | |||
* 通过房间号查询游戏ID | |||
* <pre> | |||
* 请求: {@code QueryRoomRequest} | |||
* </pre> | |||
*/--]] | |||
Query_Room_Request = 0x0201, | |||
--[[/** | |||
* 通过房间号查询游戏ID的结果 | |||
* <pre> | |||
* 推送: {@code QueryRoomResponse} | |||
* </pre> | |||
*/--]] | |||
Query_Room_Response = 0x0202, | |||
--[[/** | |||
* 服务器透传php推送消息协议 | |||
* <pre> | |||
* 推送: {@code GetPhpMessageResponse} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_PHP_MESSAGE = 0x0c0c, | |||
} | |||
-- /////////////////////////////////////////////////////////////////////////////////////// -- | |||
QueryRoomRequest = defClass("QueryRoomRequest" | |||
-- 供查询的游戏列表 | |||
, defVar("gameIdList", VT_String, "") | |||
-- 房间ID | |||
, defVar("roomId", VT_Int, 0) | |||
-- 扩展字段 | |||
, defVar("extStr", VT_String, "") | |||
) | |||
QueryRoomResponse = defClass("QueryRoomResponse" | |||
-- 0; 找到对应的房间 1: 房间不存在 | |||
, defVar("result", VT_Short, 0) | |||
-- 房间ID | |||
, defVar("roomId", VT_Int, 0) | |||
-- result为1时,此数据为0, 找到则为对应的游戏id | |||
, defVar("gameId", VT_Short, 0) | |||
-- 扩展字段 | |||
, defVar("extStr", VT_String, "") | |||
) | |||
-- 创建房间请求 | |||
CreateRoomRequest = defClass("CreateRoomRequest" | |||
-- 游戏id | |||
, defVar("gameId", VT_Short, 0) | |||
-- 底注 | |||
, defVar("basechips", VT_Int, 0) | |||
-- 总局数 | |||
, defVar("totalGameNum", VT_Short, 0) | |||
-- 需要的房卡信息 | |||
, defVar("requireCards", VT_Int, 0) | |||
-- 进入游戏的方式 //0:游戏开始后不允许进人,1:游戏开始后可以进人 | |||
, defVar("enterFlag", VT_Short, 0) | |||
-- json格式 ,不同游戏内容不一样 | |||
, defVar("gameInfo", VT_String, "") | |||
-- 創建者的用户信息 | |||
, defVar("userInfo", VT_String, "") | |||
) | |||
-- 进入房间成功,则读取房间数据 | |||
CreateRoomEntitySuccess = defClass("CreateRoomEntitySuccess" | |||
-- 展示的房间id | |||
, defVar("iShowTid", VT_Int, 0) | |||
-- 服务id, 客户端无需关注 | |||
, defVar("serverId", VT_Int, 0) | |||
-- gameId | |||
, defVar("gameId", VT_Int, 0) | |||
-- 游戏信息 | |||
, defVar("gameInfo", VT_String, "") | |||
) | |||
-- 进入房间失败,数据为空 | |||
CreateRoomEntityFailed = defClass("CreateRoomEntityFailed" | |||
) | |||
-- 创建房间结果 | |||
CreateRoomEntity = defClass("CreateRoomEntity" | |||
-- 游戏id | |||
--1房卡数量不够,当result不为0时,则无下面3个参数 | |||
, defVar("result", VT_Short, 0) | |||
-- 扩展自定义数据 | |||
, localVar("custom", VT_Int) | |||
) | |||
CreateRoomEntityType = | |||
{ | |||
[1] = { Data = CreateRoomEntitySuccess}, | |||
[2] = { Data = CreateRoomEntityFailed}, | |||
} | |||
CreateRoomDataFactories = {}; | |||
for i , v in pairs(CreateRoomEntityType) do | |||
CreateRoomDataFactories[v.Data] = { conditionDataType = i, } | |||
end | |||
local newBindableArray = require("luaScript.Protocol.BindableArray"); | |||
local function newCreateRoomResponse(defaultValue) | |||
return newBindableArray(); | |||
end | |||
local function readCreateRoomResponse(stream) | |||
local obj = CreateRoomEntity:read(stream); | |||
print("xxxx readed:" , table.toString(obj)); | |||
if obj.result == 0 then | |||
obj.custom = CreateRoomEntityType[1].Data:read(stream); | |||
else | |||
obj.custom = CreateRoomEntityType[2].Data:read(stream); | |||
end | |||
return obj; | |||
end | |||
local function writeCreateRoomResponse(value , stream) | |||
local cls = rawget(value.custom , "NetVar"); | |||
--[[ | |||
local conditionType = NotifyDataFactories[cls]; | |||
if conditionType == nil then | |||
error("发往服务器时发现了不存在的conditionType:" .. tostring(conditionType)); | |||
end | |||
--]] | |||
-- 写入数据 | |||
CreateRoomEntity:write(stream , value); | |||
cls:write(stream , value.custom); | |||
end | |||
-- 创建房间结果 | |||
CreateRoomResponseCreator = VT_Custom("CreateRoomResponseCreator" , newCreateRoomResponse , readCreateRoomResponse , writeCreateRoomResponse) | |||
CreateRoomResponse = defClass("CreateRoomResponse" | |||
, defVar("info", CreateRoomResponseCreator) | |||
) | |||
-- 创建房间时,玩家已经在房间里面 | |||
CreateRoomResponseIn = defClass("CreateRoomResponseIn" | |||
-- 桌子信息 | |||
, defVar("tid", VT_Int, 0) | |||
-- 游戏服务id | |||
, defVar("serverId", VT_Int, 0) | |||
-- 保留字段 | |||
, defVar("res", VT_Int, 0) | |||
-- 服务等级 | |||
, defVar("serverLevel", VT_Short, 0) | |||
-- 游戏id | |||
, defVar("gameId", VT_Short, 0) | |||
) | |||
-- 申请加入私人房 | |||
JoinRoomRequest = defClass("JoinRoomRequest" | |||
-- 游戏id | |||
, defVar("gameId", VT_Short, 0) | |||
-- 展示的房间id | |||
, defVar("inputTid", VT_Int, 0) | |||
-- 用户信息 | |||
, defVar("userInfo", VT_String, 0) | |||
) | |||
-- 0x8001 : 玩家已经在房间里面了,则直接发送真实房间号,申请进入房间 | |||
EnterRoomRequest = defClass("EnterRoomRequest" | |||
-- 房间真实id | |||
, defVar("tid", VT_Int, 0) | |||
-- nUserId | |||
, defVar("nUserId", VT_Int, 0) | |||
-- 用户信息 | |||
, defVar("userInfo", VT_String, "") | |||
) | |||
-- 0x8017 | |||
EnterRoomResponse = defClass("EnterRoomResponse" | |||
-- 总局数 | |||
, defVar("totalGameNum", VT_Short, 0) | |||
-- 房间号 | |||
, defVar("ShowTableId", VT_Int, 0) | |||
-- 游戏id | |||
, defVar("gameId", VT_Int, 0) | |||
-- 游戏信息,json格式,同创建房间 | |||
, defVar("strGameInfo", VT_String, "") | |||
-- 茶馆id,大于0说明用户在茶馆中 | |||
, defVar("nClubId", VT_Int, 0) | |||
) | |||
-------------------- | |||
FastJoinRoomlyRequest = defClass("FastJoinRoomlyRequest" | |||
-- 游戏id列表, 用逗号隔开,如“1,2,3” 则表示此合集包含游戏1,2,3 | |||
, defVar("gameIdList", VT_String, "") | |||
-- 房间号 | |||
, defVar("roomId", VT_Int, 0) | |||
-- 用户信息 | |||
, defVar("userInfo", VT_String, "") | |||
) | |||
getRoomListRequest = defClass("getRoomListRequest" | |||
-- 游戏类型 | |||
, defVar("gameId", VT_Short, 0) | |||
-- 游戏id | |||
, defVar("uid", VT_Int, 0) | |||
) | |||
roomList = defClass("roomList" | |||
-- 桌子的ID | |||
, defVar("nShowTableId", VT_Int, 0) | |||
-- 总局数 | |||
, defVar("nTotalGameNum", VT_Short, 0) | |||
-- 当前人数 | |||
, defVar("nUserCount", VT_Short, 0) | |||
-- 最大人数 | |||
, defVar("nMaxUserCount", VT_Short, 0) | |||
-- 游戏信息 json格 式,同创建房间json | |||
, defVar("strGameInfo", VT_String, "") | |||
) | |||
getRoomListResponse = defClass("getRoomListResponse" | |||
-- 桌子的ID | |||
, defVar("roomList", VT_Vector(roomList), {}) | |||
) | |||
-- //////////////////////////////////// 以上是消息结构的定义 //////////////////////////////////// -- | |||
-- //////////////////////////////////// 以下是服务器消息的处理 //////////////////////////////////// -- | |||
-- 请求创建房间 | |||
function Hall:requestCreateRoom(request) | |||
-- 为了收到服务器返回的结果时能正确接收房间消息 | |||
-- 这里应该先加载房间协议 | |||
local gameInfo = {} | |||
local gameType = nil | |||
if request.gameInfo then | |||
gameInfo = json.decode(request.gameInfo) | |||
gameType = gameInfo.gamerule or 0 | |||
end | |||
app:changeGameProtocol(request.gameId or 0,gameType); | |||
logD("Hall:requestCreateRoom() request = ", table.tostring(request)) | |||
app.waitDialogManager:showWaitNetworkDialog(); | |||
self:sendResponse{cmd = HallCmd.CreateRoomRequest , sender = request}; | |||
end | |||
-- 创建房间结果 - 创建房间的结果,成功或者失败 | |||
function Hall:onCreateRoomResponse(status, response) | |||
print("Hall:onCreateRoomResponse(), ", table.tostring(response)) | |||
app.waitDialogManager:closeWaitNetworkDialog(); | |||
local errCode = | |||
{ | |||
[0] = "创建房间成功", | |||
[1] = PLN.CURRENCY_NOT_ENOUGH, | |||
[2] = "达到最高开房限制", | |||
} | |||
-- 不成功则弹出提示 | |||
if response.info.result and response.info.result ~= 0 then | |||
showTooltip(errCode[response.info.result] or tostring(response.info.result)); | |||
return; | |||
end | |||
if cc.Application:getInstance():getTargetPlatform() == 0 then | |||
cc.UserDefault:getInstance():setIntegerForKey("LastRoomID",response.info.custom.iShowTid) | |||
cc.UserDefault:getInstance():flush() | |||
end | |||
-- 如果加入失败,服务器会通过 0x8005 下发房间数据 | |||
-- 如果加入成功,服务器会通过 0x8007 或 0x8009 下发房间数据 | |||
-- 请到对应的 ProtocolRoom 里面去处理 | |||
end | |||
-- 创建房间结果 - 玩家已经在房间里面了 | |||
function Hall:onCreateRoomResponseIn(status, response) | |||
print("Hall:onCreateRoomResponseIn(), ", table.tostring(response)) | |||
app.waitDialogManager:closeWaitNetworkDialog(); | |||
-- 服务器告知玩家已经在房间里面了 | |||
-- 则直接申请回到房间 | |||
--这里应该加入协议切换类型,在金币场多次点后,第二次判断在房间里面,收到此消息,于是从金币场切回了房卡的协议去了 | |||
--[[ [2019-07-04 16:04:15][LUA] Hall:onCreateRoomResponseIn(), { | |||
["gameId"] = 2, | |||
["res"] = 1, | |||
["serverId"] = 3, | |||
["serverLevel"] = 20, | |||
["tid"] = 198656, | |||
}--]] | |||
local protocolType = PROTOCOL_TYPE.COMMON | |||
if response.serverLevel and response.serverLevel > 1 then | |||
protocolType = PROTOCOL_TYPE.COIN | |||
end | |||
self:requestEnterRoom(response.gameId,response.tid,protocolType); | |||
end | |||
-- 申请加入房间 | |||
function Hall:requestJoinRoom(gameId, tableId) | |||
print("Hall:requestJoinRoom(), ", gameId, tableId ) | |||
local request = JoinRoomRequest:new(); | |||
request.gameId = gameId; | |||
request.inputTid = tableId; | |||
request.userInfo = app.user.userInfo; | |||
local function doRequest() | |||
app:changeGameProtocol(gameId, 1); | |||
print("Hall:requestJoinRoom(), ", table.tostring(request)) | |||
app.waitDialogManager:showWaitNetworkDialog(); | |||
self:sendResponse{cmd = HallCmd.JoinRoomRequest , sender = request}; | |||
end | |||
-- 检查一下这个子游戏是否需要更新 | |||
if app.subGameManager then | |||
local isInstall = app.subGameManager:isInstaller(gameId) | |||
local isNeedUpdate = app.subGameManager:isNeedUpdate(gameId) | |||
if not isInstall or isNeedUpdate then | |||
downloadSubGame(gameId, doRequest) | |||
return; | |||
end | |||
end | |||
doRequest() | |||
end | |||
-- 加入房间结果 | |||
function Hall:onJoinRoomResponse(status, response) | |||
print("Hall:onJoinRoomResponse(), ", table.tostring(response)) | |||
app.waitDialogManager:closeWaitNetworkDialog(); | |||
local errCode = response.info.result | |||
if errCode ~= 0 then | |||
local errString = ENTER_ROOM_RET_STR[errCode] or "房间不存在" | |||
showTooltip(errString); | |||
return; | |||
end | |||
--[[ | |||
-- 展示的房间id | |||
, defVar("iShowTid", VT_Int, 0) | |||
-- 服务id, 客户端无需关注 | |||
, defVar("serverId", VT_Int, 0) | |||
-- gameId | |||
, defVar("gameId", VT_Int, 0) | |||
-- 游戏信息 | |||
, defVar("gameInfo", VT_String, "") | |||
]] | |||
local gameId = response.info.custom.gameId | |||
local gameInfo = json.decode(response.info.custom.gameInfo) | |||
local gameType = gameInfo.gamerule | |||
-- 为了收到服务器返回的结果时能正确接收房间消息 | |||
-- 这里应该先加载房间协议 | |||
app:changeGameProtocol(gameId,gameType); | |||
-- 如果加入失败,服务器会通过 0x8005 下发房间数据 | |||
-- 如果加入成功,服务器会通过 0x8007 或 0x8009 下发房间数据 | |||
-- 请到对应的 ProtocolRoom 里面去处理 | |||
end | |||
-- 快速加入房间 | |||
function Hall:requestFastJoinRoom(roomId) | |||
print("Hall:requestFastJoinRoom()", roomId) | |||
local listIds = app.subGameManager:getGameListInstalled() | |||
local request = FastJoinRoomlyRequest:new(); | |||
request.gameIdList = listIds | |||
request.roomId = roomId; | |||
request.userInfo = app.user.userInfo; | |||
print("Hall:requestFastJoinRoom() ", table.tostring(request)) | |||
app.waitDialogManager:showWaitNetworkDialog(); | |||
self:sendResponse{cmd = HallCmd.FastJoinRoomlyRequest , sender = request}; | |||
end | |||
-- 0x8001 : 请求回到房间,玩家已经在房间了,使用此接口 | |||
function Hall:requestEnterRoom(gameId, tableId, protocolType) | |||
print("Hall:requestEnterRoom()", tableId) | |||
local request = EnterRoomRequest:new(); | |||
request.tid = tableId | |||
request.nUserId = app.user.loginInfo.uid; | |||
request.userInfo = app.user.userInfo; | |||
app:changeGameProtocol(gameId, 1, protocolType); | |||
print("Hall:requestEnterRoom() ", table.tostring(request)) | |||
-- app.waitDialogManager:showWaitNetworkDialog(); | |||
self:sendResponse{cmd = HallCmd.GAME_COMMAND_ENTER_ROOM , sender = request}; | |||
end | |||
-- 0x8017 : 对 0x8001 的回复 | |||
function Hall:onEnterRoomResponse(status, response) | |||
print("Hall:onEnterRoomResponse", table.tostring(response)) | |||
app.waitDialogManager:closeWaitNetworkDialog(); | |||
if not response then | |||
return; | |||
end | |||
local gameid = response.gameId | |||
local gameRule = nil | |||
local gameInfo = json.decode(response.strGameInfo) | |||
if response.ShowTableId then | |||
setGameRoomId(response.ShowTableId) | |||
end | |||
if gameInfo then | |||
gameRule = gameInfo.gamerule or 0 | |||
--桌子下标 | |||
app.club_php.tableIdx = gameInfo.tableIdx | |||
end | |||
local clubID = response.nClubId; | |||
if clubID > 0 then | |||
--茶馆id>0,说明玩家从茶馆中开房 | |||
app.club_php.clubID = clubID; | |||
else | |||
app.club_php.clubID = 0; | |||
end | |||
-- 为了收到服务器返回的结果时能正确接收房间消息 | |||
-- 这里应该先加载房间协议 | |||
app:changeGameProtocol(gameid, gameRule); | |||
end | |||
-- 请求获取房间列表 | |||
function Hall:requestGetRoomList(gameId) | |||
local request = getRoomListRequest:new() | |||
request.gameId = gameId | |||
request.uid = app.user.loginInfo.uid | |||
self:sendResponse{cmd = HallCmd.getRoomListRequest , sender = request}; | |||
end | |||
-- 获取房间结果 | |||
function Hall:onGetRoomListResponse(status, response) | |||
print("Hall:onGetRoomListResponse(), ", table.tostring(response)) | |||
self:dispatchEvent({name = "onGetRoomListResponse", response = response}); | |||
end | |||
-- 通过房间号查询游戏ID | |||
-- 查询完成后返回 gameid, roomid | |||
function Hall:queryRoomId(roomId, callback) | |||
if not self.queryCallbackList then | |||
self.queryCallbackList = {} | |||
end | |||
if not self.queryIndex then | |||
self.queryIndex = 0 | |||
end | |||
self.queryIndex = self.queryIndex + 1 | |||
local extStr = tostring(self.queryIndex) | |||
self.queryCallbackList[extStr] = callback | |||
local gameIds = {} | |||
for k,v in pairs(app.serverConfigs.subGameList) do | |||
table.insert(gameIds,v.gameId or 0) | |||
end | |||
local ids = nil; | |||
for id,v in pairs(gameIds) do | |||
if v > 0 then | |||
if not ids then | |||
ids = tostring(v) | |||
else | |||
ids = tostring(ids) .. "," .. tostring(v) | |||
end | |||
end | |||
end | |||
local request = QueryRoomRequest:new() | |||
request.gameIdList = ids | |||
request.roomId = roomId | |||
request.extStr = extStr | |||
logD("Hall:queryRoomId() ", table.tostring(request)) | |||
self:sendResponse{cmd = HallCmd.Query_Room_Request , sender = request}; | |||
end | |||
-- 查询房间结果 | |||
function Hall:onQueryRoomResponse(status, response) | |||
print("Hall:onQueryRoomResponse(), ", table.tostring(response)) | |||
local result = response.result | |||
local gameId = response.gameId | |||
local roomId = response.roomId | |||
local extStr = response.extStr; | |||
local queryCallback = self.queryCallbackList[extStr] | |||
if queryCallback then | |||
queryCallback(gameId, roomId) | |||
end | |||
end | |||
--服务器透传php推送消息协议 | |||
function Hall:onGetPhpMessageResponse(status, response) | |||
logD("Hall:onGetPhpMessageResponse(), response = ", table.tostring(response)) | |||
--[[ | |||
-- 如果5分钟之内没有再次收到推送消息,则上传日志 | |||
if self.timerHandler then | |||
cc.Director:getInstance():getScheduler():unscheduleScriptEntry(self.timerHandler); | |||
self.timerHandler = nil | |||
end | |||
self.unschedule = cc.Director:getInstance():getScheduler():scheduleScriptFunc(function() | |||
uploadLogs("PHPMESSAGE") | |||
end, 5 * 60, false) | |||
--]] | |||
-- 以下是正常逻辑 | |||
if not response then | |||
logD("Hall:onGetPhpMessageResponse", "response is nil"); | |||
return ; | |||
end | |||
local message = json.decode(response.stringValue); | |||
if message == nil then | |||
return | |||
end | |||
logD("Hall:onGetPhpMessageResponse(), message = ", table.tostring(message)) | |||
if tonumber(message.type) == 10 then | |||
-- 充值钻石 | |||
local attr = message.attr | |||
logD("Hall:onGetPhpMessageResponse(), attr = ", table.tostring(attr)) | |||
app.user.loginInfo.curCardNum = tonumber(attr.curr_card) | |||
app.user.loginInfo.historyCardNum = tonumber(attr.total_card) | |||
elseif tonumber(message.type) == 12 then | |||
-- 充值欢乐豆 | |||
local attr = message.attr | |||
app.user.loginInfo.curBeanNum = tonumber(attr.curr_beans) | |||
self:dispatchEvent({name = GAME_EVENT.RECHARGE_RESULT}) | |||
elseif tonumber(message.type) == 13 then | |||
-- 充值礼券 | |||
local attr = message.attr | |||
app.user.loginInfo.curLiquanNum = tonumber(attr.curr_coupons) | |||
self:dispatchEvent({name = "couponsAdd", attr = attr}) | |||
elseif tonumber(message.type) == 14 then | |||
-- 客户端实时上传日志 | |||
if message.attr and message.attr.date then | |||
if logFileManager then | |||
logFileManager:uploadFilesByDay(message.attr.date) | |||
end | |||
end | |||
else | |||
-- 这里处理不了的,就发送事件出去,让能处理的人处理 | |||
app:dispatchEvent({name = "onPhpMessage",msg = message}); | |||
end | |||
end | |||
-- //////////////////////////////////// 以上是服务器消息的处理 //////////////////////////////////// -- | |||
function Hall:ctor(net) | |||
Hall.super.ctor(self , net); | |||
-- 玩家已经在房间里面了,则发送此消息,请求进入房间 | |||
self:defMsgFunc{name = "enterRoomRequest", cmd = HallCmd.GAME_COMMAND_ENTER_ROOM, sender = EnterRoomRequest}; | |||
-- 推送创建房间结果(正常进入)如果进房成功,服务器会快速分配桌子给玩家,分配成功返回进入桌子成功消息 RoomCmd.GAME_COMMAND_LOGIN_GAME_SUCCESS | |||
self:defPushMsg{cmd = HallCmd.CreateRoomResponse , reader = CreateRoomResponse, func = handler(self , self.onCreateRoomResponse)}; | |||
-- 推送创建房间结果(玩家已经在房间里面) | |||
self:defPushMsg{cmd = HallCmd.CreateRoomResponseIn , reader = CreateRoomResponseIn, func = handler(self , self.onCreateRoomResponseIn)}; | |||
-- 推送加入房间结果,同快速加入结果 | |||
self:defPushMsg{cmd = HallCmd.JoinRoomResponse , reader = CreateRoomResponse, func = handler(self , self.onJoinRoomResponse)}; | |||
-- 发8001返回此消息,为游戏房间信息 | |||
self:defPushMsg{cmd = HallCmd.GAME_COMMAND_ENTER_ROOM_RESPONSE , reader = EnterRoomResponse, func = handler(self , self.onEnterRoomResponse)}; | |||
-- 房间列表结果 | |||
self:defPushMsg{cmd = HallCmd.getRoomListResponse , reader = getRoomListResponse, func = handler(self , self.onGetRoomListResponse)}; | |||
self:defPushMsg{cmd = HallCmd.Query_Room_Response , reader = QueryRoomResponse, func = handler(self , self.onQueryRoomResponse)}; | |||
self:defPushMsg{cmd = HallCmd.GAME_COMMAND_PHP_MESSAGE, reader = StringPacket, func = handler(self, self.onGetPhpMessageResponse)} | |||
end | |||
return Hall; |
@@ -0,0 +1,166 @@ | |||
local Heart = class("Heart" , require("luaScript.Protocol.Protocol")) | |||
local HeartCmd = { | |||
--[[ | |||
* 心跳包 | |||
* <pre> | |||
* 请求: {@link HeartBeatRequest} | |||
* 响应: {@link HeartBeatResponse} | |||
* </pre> | |||
--]] | |||
HEART_BEAT = 0x2008, | |||
} | |||
-- 服务器返回的心跳包 | |||
local HeartBeatResponse = defClass("HeartBeatResponse" | |||
-- 服务器的当前时间,从1970开始的毫秒数 | |||
, defVar("serverTime", VT_Long, 0) | |||
) | |||
-- 每隔多久发一次心跳包 | |||
local HeartBeatTime = 5 | |||
-- 心跳包多久没有收到就认为超时了 | |||
local NetOverTime = 8; | |||
function Heart:onLoginToUserProtocol() | |||
logD("Heart:onLoginToUserProtocol()") | |||
-- 开始发送心跳包 | |||
self.net.Socket:setOption("HeartBeatCode" , HeartCmd.HEART_BEAT); | |||
self.net.Socket:setOption("HeartBeatTime" , HeartBeatTime * 1000); | |||
self:resetNetOverTimer(); | |||
end | |||
-- 服务器心跳回调 | |||
function Heart:onUpdateServerTime(status, response) | |||
logD("Heart:onUpdateServerTime()") | |||
if status ~= 0 then | |||
print("心跳包返回错误代码 statusCode:" .. tostring(status)) | |||
return; | |||
end; | |||
-- 更新 | |||
self.heartBeatResponse = response:updateTo(self.heartBeatResponse); | |||
self.TimeEclipsed = response.serverTime / 1000; | |||
self.TimeStart = os.time(); | |||
-- 记录下上次消息时间 | |||
self.LastNetMessageTime = self.TimeStart; | |||
self:resetNetOverTimer() | |||
end | |||
function Heart:onNetProcessMessage(event) | |||
self.LastNetMessageTime = os.time(); | |||
end | |||
-- 设置超时定时器 | |||
function Heart:resetNetOverTimer() | |||
logD("Heart:resetNetOverTimer()") | |||
if not tolua.isnull(self.TimeoutAction) then | |||
app.mainScene:stopAction(self.TimeoutAction); | |||
end | |||
self.TimeoutAction = nil; | |||
self.NeedToReconnect = false; | |||
if app.mainScene then | |||
local t1 = os.time() | |||
local function onTimeout() | |||
logD("Heart:resetNetOverTimer() 心跳超时时间 = ", os.time()) | |||
logD("Heart:resetNetOverTimer() 误差超时时间 = ", (os.time()-t1)) | |||
-- 两帧之后,再检查是否有收到消息,如果还没收到,就认为超时 | |||
local lastTime = self.LastNetMessageTime; | |||
local curTime = os.time(); | |||
local deltaTime = curTime - lastTime; | |||
logD("Heart:resetNetOverTimer() curTime = ", curTime); | |||
logD("Heart:resetNetOverTimer() lastTime = ", lastTime); | |||
logD("Heart:resetNetOverTimer() deltaTime = ", deltaTime); | |||
if deltaTime >= NetOverTime then | |||
-- 这里不一定是断线了,如果充值的时候,游戏渲染窗口就不渲染了整个游戏就更新了,网络消息也不会触发脚本了 | |||
-- 但是这个时候网络其实是没有断开的 | |||
-- 延迟一帧执行,给一次机会 | |||
local function reconnectToServer() | |||
if self.NeedToReconnect and not app.user.kickOffState then | |||
logD("Heart:resetNetOverTimer() 已经[" .. deltaTime .. "]秒没有收到服务器消息了,说明网络有问题,重连咯"); | |||
-- 断开网络后 会自动重连 不需要手动调用reconnect | |||
self.net:close(); | |||
-- 马上重连 | |||
--self.net:reConnect(); | |||
self.NeedToReconnect = false | |||
end | |||
end | |||
self.NeedToReconnect = true | |||
runInNextFrame(reconnectToServer) | |||
else | |||
-- 说明在定时器期间又收到服务器的消息但没有收到心跳包 | |||
-- 再给一次机会,不要断线 | |||
runInNextFrame(function() | |||
self:resetNetOverTimer() | |||
end) | |||
end | |||
self.TimeoutAction = nil; | |||
end | |||
logD("Heart:resetNetOverTimer() 心跳开始本地时间 = ", t1); | |||
-- 发完心跳包一段时间后还没有新消息,就说明网络死了 | |||
self.TimeoutAction = app.mainScene:runActions(cc.DelayTime:create(NetOverTime), onTimeout); | |||
end | |||
end | |||
-- 停止 | |||
function Heart:stop() | |||
end | |||
-- 服务器时间(返回秒数) | |||
function Heart:getServerTime() | |||
local now = os.time() | |||
local seconds = now - self.TimeStart; | |||
return math.ceil(self.TimeEclipsed + seconds); | |||
end | |||
-- 服务器时间(日期形式返回) | |||
function Heart:getServerDateTime() | |||
return BeijingTime.dateFunc(self:getServerTime()) | |||
end | |||
--知道已经断开连接停止检测 | |||
function Heart:onStopHeart() | |||
if not tolua.isnull(self.TimeoutAction) then | |||
app.mainScene:stopAction(self.TimeoutAction); | |||
end | |||
end | |||
function Heart:ctor(net) | |||
Heart.super.ctor(self , net); | |||
self.heartBeatResponse = HeartBeatResponse:new(); | |||
-- 上次心跳包服务器时间 | |||
self.TimeEclipsed = 0; | |||
-- 上次心跳包客户端时间 | |||
self.TimeStart = 0; | |||
-- 上次更新消息时间 | |||
self.LastNetMessageTime = 0 | |||
-- 注册网络消息更新事件 | |||
app:addEventListener("onRecvMsgFromGameServer" , handler(self , self.onNetProcessMessage)); | |||
-- 注册登录事件 | |||
app:addEventListener("onGameServerConnected" , handler(self , self.onLoginToUserProtocol)); | |||
app:addEventListener("onGameServerDisConnect" , handler(self , self.onStopHeart)); | |||
-- 注册心跳回调函数 | |||
self:defPullMsg{name = "heartBeat", cmd = HeartCmd.HEART_BEAT , resCmd = HeartCmd.HEART_BEAT, reader = HeartBeatResponse , func = handler(self , self.onUpdateServerTime)}; | |||
self:defPushMsg{cmd = HeartCmd.HEART_BEAT , reader = HeartBeatResponse , func = handler(self , self.onUpdateServerTime)}; | |||
end | |||
return Heart; |
@@ -0,0 +1,531 @@ | |||
local ProtocolPhpShop = class("ProtocolPhpShop") | |||
--[[ | |||
--充值项数据 | |||
["10023"] = | |||
{ | |||
["id"] = 10023, | |||
["name"] = 18房卡, | |||
["icon"] = http://api.dingdingqipai.com/pic/d_18.png, | |||
["desc"] = 18房卡, | |||
["number"] = 18, | |||
["price"] = 18, | |||
["currency"] = 2, -- 购买类型,1为房卡,2为人民币,3为金币 | |||
["order"] = 2, -- 排序 数字越小越在前面 | |||
["privilege_icon"] = http://api.dingdingqipai.com/pic/diamond_68.png, -- 特权角标 | |||
["product_id"] = , -- 应用商店ID | |||
["pay_type"] = -- 支付方式 | |||
{ | |||
[1] = | |||
{ | |||
["id"] = 2, | |||
["name"] = 微信支付, | |||
}, | |||
[2] = | |||
{ | |||
["id"] = 3, | |||
["name"] = H5支付, | |||
}, | |||
}, | |||
iconFile = "", -- 图标在本地保存的文件名 | |||
privilegeFile = "", -- 特权角标在本地保存的文件名 | |||
}, | |||
--]] | |||
local UserCmd = | |||
{ | |||
PHP_USER_LOGIN = "user.login", -- 登录PHP | |||
PHP_USER_KEEPALIVE = "user.keepalive", -- 保持会话 | |||
PHP_SHOP_INFO = "shop.info", -- 商城列表 | |||
PHP_SHOP_BUY = "shop.buy", -- 购买商品 | |||
PHP_SHOP_ORDER = "order.unified", -- 获取订单号 | |||
PHP_SHOP_RECEIPT = "order.receipt", -- 支付成功后发送给服务器验证订单 | |||
PHP_ZHANJI_INFO = "gamb.info", -- 战绩数据 | |||
PHP_ZHANJI_DETAIL = "gamb.deatailall", -- 单局战绩数据 | |||
PHP_EXCHANGE = "platform.exchange", -- 兑换房卡 | |||
PHP_RMB_EXCHANGE = "platform.rmborder", -- 人民币支付 | |||
PHP_RMB_EXCHANGE_H5 = "platform.payInRmbByH5", -- 人民币h5支付 | |||
PHP_LIQUAN_RECORD = "shop.couponsRecord",--礼券兑换记录 | |||
} | |||
function ProtocolPhpShop:ctor() | |||
-- 添加分发事件的组件 | |||
cc.GameObject.extend(self) | |||
self:addComponent(require("luaScript.cc.components.behavior.EventProtocol"):new()):exportMethods() | |||
self.phpUrl = getGlobalPhpUrl() | |||
-- 商店所有图标的更新时间 | |||
self.shopIconTimesKey = "shopIconTimes"; | |||
self.shopIconTimes = {} | |||
-- 房卡充值数据 | |||
self.shopData = nil | |||
-- 房卡充值记录 | |||
self.shopRecordData = nil | |||
-- 金币商城数据 | |||
end | |||
-- 请求获取商店信息 | |||
function ProtocolPhpShop:getShopInfo() | |||
local tt = {} | |||
tt.action = UserCmd.PHP_SHOP_INFO | |||
tt.uid = app.user.loginInfo.uid | |||
tt.token = app.user.loginInfo.token | |||
tt.app = getAppId() | |||
tt.newWx = 1 | |||
logD("ProtocolPhpShop:getShopInfo_send", table.tostring(tt)) | |||
httpPost(self.phpUrl, tt, handler(self, self.onGetShopInfoResponse)) | |||
end | |||
-- 获取商店数据的结果 | |||
function ProtocolPhpShop:onGetShopInfoResponse(status, response) | |||
logD("ProtocolPhpShop:onGetShopInfoResponse()", status, response) | |||
if status ~= "successed" then | |||
logE("商店数据拉取失败") | |||
return | |||
end | |||
local data = json.decode(response) | |||
if not data or type(data) ~= "table" or data.code ~= 200 then | |||
logE("商店数据错误") | |||
return | |||
end | |||
logD("ProtocolPhpShop:onGetShopInfoResponse() data = ", table.tostring(data)) | |||
--self.shopData = data.result | |||
self.shopData = {} | |||
for k,v in pairs(data.result) do | |||
self.shopData[v.id] = v; | |||
end | |||
self:dispatchEvent({name = "getShopInfoSuccessed"}); | |||
end | |||
-- 请求获取商城购买记录 | |||
function ProtocolPhpShop:requestGetShopRecord() | |||
local tt = | |||
{ | |||
action= "shop.record", | |||
uid = app.user.loginInfo.uid, | |||
token = app.user.loginInfo.token, | |||
app = getAppId(), | |||
} | |||
httpPost(self.phpUrl, tt, handler(self, self.onGetShopRecordResponse)) | |||
end | |||
-- 获取商城购买记录的结果 | |||
function ProtocolPhpShop:onGetShopRecordResponse(status, response) | |||
logD("ProtocolPhpShop:onGetShopRecordResponse()", status, response) | |||
if status ~= "successed" then | |||
logE("获取充值记录失败") | |||
return | |||
end | |||
local data = json.decode(response) | |||
if not data or type(data) ~= "table" or data.code ~= 200 then | |||
logE("充值记录数据错误") | |||
return | |||
end | |||
logD("ProtocolPhpShop:onGetShopRecordResponse() data = ", table.tostring(data)) | |||
self.shopRecordData = data.result; | |||
self:dispatchEvent({name = "getShopRecordInfoSuccessed"}); | |||
end | |||
-- 请求购买商品 | |||
function ProtocolPhpShop:buyshop(shopid) | |||
local tt = {} | |||
tt.action = UserCmd.PHP_SHOP_BUY --//接口名 | |||
tt.uid = app.user.loginInfo.uid --//用户ID | |||
tt.platform_id = ""--//平台ID,微信则为:微信授权ID | |||
tt.platform_type = 1 --//平台类型,1为微信 | |||
tt.channel = app.config.RomSetting.ChannelId;--//渠道号 | |||
tt.token = app.user.loginInfo.token--//svr生成的32字节字符串,用于唯一验证客户端有消息 | |||
--获取版本号 | |||
local appVersion = getAppVersionNum() | |||
local resVersion = loadVersion() | |||
local versionInfo = string.format(appVersion.."."..resVersion ) | |||
tt.version = versionInfo --//客户端版本号 | |||
tt.device = ""--//设备唯一标识,如有则传,无则无需传输 | |||
tt.app = getAppId() --//应用ID | |||
tt.id = shopid | |||
tt.number = 1 | |||
log("ProtocolPhpShop:buyshop_send", table.tostring(tt)) | |||
httpPost(self.phpUrl, tt, function(status, response) | |||
log("ProtocolPhpShop:buyshop", table.tostring(response)) | |||
local tt = json.decode(response) | |||
if type(tt) ~= "table" then | |||
showPHPFailedResult("buyshop is no table") | |||
return | |||
end | |||
if tt.code == 200 then | |||
local result = tt.result | |||
local lastCardNum = app.user.loginInfo.curCardNum | |||
local lastCoinNum = app.user.loginInfo.curJingbiNum | |||
app.user.loginInfo.curCardNum = result.card | |||
--黄十八兑换道具的时候没有金币返回 | |||
if result.gold then | |||
app.user.loginInfo.curJingbiNum = result.gold | |||
showTooltip("购买成功") | |||
end | |||
result.lastCardNum = lastCardNum | |||
result.lastCoinNum = lastCoinNum | |||
self:dispatchEvent({name = "exchangeCoinSuccess", code = tt.code, response = result }); | |||
elseif tt.code == 7301 then | |||
showTooltip("兑换失败,参数错误") | |||
elseif tt.code == 7302 then | |||
if buyType == STORE_TYPE.BUY_ZUANSHI then | |||
--钻石兑换 | |||
showTooltip("兑换失败,钻石数量不足") | |||
elseif buyType == STORE_TYPE.CHANGE_LIQUAN then | |||
--礼券兑换 | |||
showTooltip("兑换失败,礼券数量不足") | |||
end | |||
elseif tt.code == 7303 then | |||
showTooltip("兑换失败,请联系客服") | |||
end | |||
-- self:dispatchEvent({name = GAME_EVENT.RECHARGE_RESULT, code = tt.code , card = app.user.loginInfo.curCardNum}); | |||
end) | |||
end | |||
-- 获取订单号 | |||
function ProtocolPhpShop:getOrderID(shopid, payType) | |||
self.shopID = shopid | |||
local itemId = 0 | |||
for k,v in pairs(self.shopData) do | |||
if k == (shopid) then | |||
itemId = k; | |||
break; | |||
end | |||
end | |||
local tt = {} | |||
tt.action = UserCmd.PHP_SHOP_ORDER --//接口名 | |||
tt.item_id = itemId --//商品ID,暂时传0 | |||
tt.uid = app.user.loginInfo.uid --//用户ID | |||
tt.app = getAppId() --//应用ID | |||
tt.pay_type = payType --//支付方式 | |||
tt.token = app.user.loginInfo.token --//登录时验证参数 | |||
log("ProtocolPhpShop:getOrderID_send", table.tostring(tt)) | |||
--app.waitDialogManager:showTransparencyMask() | |||
httpPost(self.phpUrl, tt, function(status, response) | |||
--app.waitDialogManager:closeTransparencyMask() | |||
log("ProtocolPhpShop:getOrderID", table.tostring(response)) | |||
local responseTable = json.decode(response) | |||
if type(responseTable) ~= "table" then | |||
showPHPFailedResult("getOrderID is no table") | |||
return | |||
end | |||
if type(responseTable) == "table" and tonumber(responseTable.code) ~= 200 then | |||
showPHPFailedResult("getOrderID failed 1") | |||
return | |||
end | |||
local resultInfo = responseTable.result | |||
-- 订单号 | |||
if payType == PayType.PAY_TYPE_HYB then--如果是11汇元宝支付方式 | |||
if resultInfo and not resultInfo.url then | |||
local errorMsg = resultInfo.err or "支付失败:11"; | |||
showTooltip(errorMsg); | |||
return | |||
end | |||
elseif (not resultInfo.info or not resultInfo.info.orderid) and payType~=PayType.PAY_TYPE_WEXIN_SHARE and payType ~= PayType.PAY_TYPE_ALIPAY then | |||
if resultInfo then | |||
local errorMsg = resultInfo.err; | |||
showTooltip(errorMsg); | |||
end | |||
return | |||
end | |||
if resultInfo.flag == 1 then | |||
self.orderInfo = resultInfo.info; | |||
log("获取订单成功,订单号:",resultInfo.info.orderid); | |||
if payType == PayType.PAY_TYPE_H5 then | |||
print("PAY_TYPE_H5 ProtocolPhpShop:getOrderID() url = ",resultInfo.info.orderid); | |||
app.plugin:callUrl(resultInfo.info.orderid); | |||
elseif payType == PayType.PAY_TYPE_HYB then | |||
print("PAY_TYPE_HYB ProtocolPhpShop:getOrderID() url = ",resultInfo.info.orderid); | |||
app.plugin:callUrl(resultInfo.url); | |||
elseif payType == PayType.PAY_TYPE_ALIPAY then | |||
print("PAY_TYPE_ALIPAY ProtocolPhpShop:getOrderID() url = ",resultInfo.info.orderid); | |||
app.plugin:callUrl(resultInfo.url); | |||
elseif payType == PayType.PAY_TYPE_WEXIN then | |||
app.plugin:payWeiXin(resultInfo.info); | |||
elseif payType == PayType.PAY_TYPE_WEXIN_SHARE then | |||
local info = { | |||
scene = "talk", | |||
contentType = "url", | |||
title = "川南棋牌订单", | |||
description = "支付链接", | |||
image = cc.FileUtils:getInstance():getWritablePath().."icon.png", | |||
url = resultInfo.url, | |||
imageWidth = 100, | |||
} | |||
log("分享订单:",table.tostring(info)) | |||
app.plugin:shareGame(info) | |||
end | |||
else | |||
showPHPFailedResult("getOrderID failed 2") | |||
end | |||
end) | |||
end | |||
-- 发送订单信息到服务器 | |||
function ProtocolPhpShop:postReceiptInfo(code, msg) | |||
log("ProtocolPhpShop:postReceiptInfo msg = ", table.tostring(msg)) | |||
if code == 4001 then -- 支付成功 | |||
elseif code == 4002 then -- 支付失败 | |||
showTooltip("微信支付失败!") | |||
showConfirmDialog(string.format("支付失败: %s", msg)); | |||
elseif code == 4003 then -- 支付取消 | |||
showTooltip("取消微信支付!") | |||
showConfirmDialog(string.format("支付取消: %s", msg)); | |||
elseif code == 4004 then -- 支付超过时效 | |||
showTooltip("支付超时!") | |||
end | |||
end | |||
-- 读取商店所有图标的更新时间 | |||
function ProtocolPhpShop:loadShopIconTimes() | |||
local value = loadUserInfo(self.shopIconTimesKey) | |||
self.shopIconTimes = json.decode(value) or {} | |||
end | |||
-- 保存商店所有图标的更新时间 | |||
function ProtocolPhpShop:saveShopIconTimes() | |||
local value = json.encode(self.shopIconTimes) | |||
saveUserInfo(self.shopIconTimesKey, value) | |||
end | |||
-- 获取商店图标的更新时间 | |||
function ProtocolPhpShop:getShopIconTime(fileName) | |||
if not fileName then | |||
return 0 | |||
end | |||
return self.shopIconTimes[fileName] or 0 | |||
end | |||
-- 更新商店图标的更新时间 | |||
function ProtocolPhpShop:updateShopIconTime(fileName, timeNew) | |||
if not fileName or not timeNew then | |||
return | |||
end | |||
self.shopIconTimes[fileName] = timeNew | |||
self:saveShopIconTimes() | |||
end | |||
-- 请求小游戏兑换房卡 | |||
function ProtocolPhpShop:requestExchange(orderId) | |||
local tt = | |||
{ | |||
action= UserCmd.PHP_EXCHANGE, | |||
uid = app.user.loginInfo.uid, | |||
app = getAppId(), | |||
perpayid = orderId, | |||
} | |||
logD("ProtocolPhpShop:requestExchange", table.tostring(tt)) | |||
httpPost(self.phpUrl, tt, function (status, strResponse) | |||
logD("ProtocolPhpShop:requestExchange response", strResponse) | |||
if strResponse then | |||
local response = json.decode(strResponse) | |||
dump(response) | |||
if tonumber(response.code) == 200 then | |||
app.user.loginInfo.curBeanNum = tonumber(response.result.beans) | |||
end | |||
local ret = { | |||
code = response.code, | |||
bean = app.user.loginInfo.curBeanNum, | |||
} | |||
self:dispatchEvent({name = GAME_EVENT.EXCHANGE_RESULT, ret = json.encode(ret)}) | |||
end | |||
end) | |||
end | |||
-- 请求小游戏人民币支付订单 | |||
function ProtocolPhpShop:requestRmbExchange(orderId) | |||
local tt = | |||
{ | |||
action= UserCmd.PHP_RMB_EXCHANGE, | |||
uid = app.user.loginInfo.uid, | |||
app = getAppId(), | |||
perpayid = orderId, | |||
} | |||
if isReviewVersion() then | |||
tt.audit = 1 | |||
end | |||
logD("ProtocolPhpShop:requestRmbExchange", table.tostring(tt)) | |||
httpPost(self.phpUrl, tt, function (status, strResponse) | |||
logD("ProtocolPhpShop:requestRmbExchange response", strResponse) | |||
if strResponse then | |||
local response = json.decode(strResponse) | |||
-- dump(response) | |||
if tonumber(response.code) == 200 then | |||
if response.result then | |||
if tonumber(response.result.isApple) == 1 then | |||
app.plugin:payIosPay({id=response.result.product_id, orderid=response.result.orderid}) | |||
elseif response.result.url then | |||
if PluginDevice then | |||
PluginDevice:callVoid("openUrl", response.result.url); | |||
end | |||
else | |||
app.plugin:payWeiXin(response.result) | |||
end | |||
else | |||
logD("ProtocolPhpShop:requestRmbExchange response.result is null") | |||
end | |||
end | |||
local ret = { | |||
code = response.code, | |||
-- bean = app.user.loginInfo.curBeanNum, | |||
} | |||
self:dispatchEvent({name = GAME_EVENT.EXCHANGE_RESULT, ret = json.encode(ret)}) | |||
end | |||
end) | |||
end | |||
-- 请求小游戏人民币支付订单 | |||
function ProtocolPhpShop:requestRmbExchangeH5(orderId) | |||
local tt = | |||
{ | |||
action= UserCmd.PHP_RMB_EXCHANGE_H5, | |||
uid = app.user.loginInfo.uid, | |||
app = getAppId(), | |||
perpayid = orderId, | |||
} | |||
if isReviewVersion() then | |||
tt.audit = 1 | |||
end | |||
logD("ProtocolPhpShop:requestRmbExchange", table.tostring(tt)) | |||
httpPost(self.phpUrl, tt, function (status, strResponse) | |||
logD("ProtocolPhpShop:requestRmbExchange response", strResponse) | |||
if strResponse then | |||
local response = json.decode(strResponse) | |||
-- dump(response) | |||
if tonumber(response.code) == 200 then | |||
if response.result then | |||
if response.result.url and PluginDevice then | |||
PluginDevice:callVoid("openUrl", response.result.url); | |||
end | |||
else | |||
logD("ProtocolPhpShop:requestRmbExchange response.result is null") | |||
end | |||
end | |||
local ret = { | |||
code = response.code, | |||
-- bean = app.user.loginInfo.curBeanNum, | |||
} | |||
self:dispatchEvent({name = GAME_EVENT.EXCHANGE_RESULT, ret = json.encode(ret)}) | |||
end | |||
end) | |||
end | |||
-- 请求礼券兑换记录 | |||
function ProtocolPhpShop:requestLiquanRecord() | |||
local tt = | |||
{ | |||
action= UserCmd.PHP_LIQUAN_RECORD, | |||
uid = app.user.loginInfo.uid, | |||
app = getAppId(), | |||
token = app.user.loginInfo.token, | |||
} | |||
logD("ProtocolPhpShop:requestLiquanRecord_send", table.tostring(tt)) | |||
httpPost(self.phpUrl, tt, function (status, strResponse) | |||
logD("ProtocolPhpShop:requestLiquanRecord response", strResponse) | |||
if status ~= "successed" then | |||
logD("获取礼券兑换记录失败") | |||
return | |||
end | |||
local data = json.decode(strResponse) | |||
if not data or type(data) ~= "table" or data.code ~= 200 then | |||
logD("获取礼券兑换记录数据错误") | |||
return | |||
end | |||
logD("ProtocolPhpShop:requestLiquanRecord() data = ", table.tostring(data)) | |||
self.liquanRecordData = data.result.lists; | |||
self:dispatchEvent({name = "getShopLiquanRecordSuccessed"}); | |||
end) | |||
end | |||
--点击某个类型才下载某个类型的图片 | |||
function ProtocolPhpShop:onDownLoadImageByType(selecttype) | |||
if not self.shopData then | |||
return | |||
end | |||
local function checkIcon(id, url) | |||
local iconUrl, iconTimeNew = convertIconUrl(url) | |||
local fileName = getImageNameFromUrl(iconUrl) | |||
local iconTimeOld = self:getShopIconTime(fileName) | |||
if not iconTimeNew then | |||
iconTimeNew = 1 | |||
end | |||
if tonumber(iconTimeOld) <= 0 or tonumber(iconTimeOld) ~= tonumber(iconTimeNew) then | |||
getImageFromUrlWithTime(iconUrl, fileName, nil, function() | |||
-- 记录图片下载的最后时间 | |||
self:updateShopIconTime(fileName, iconTimeNew) | |||
-- 通知下载完成 | |||
self:dispatchEvent({name = "downloadImageSuccessed", id = id}); | |||
end) | |||
end | |||
return fileName; | |||
end | |||
-- 遍历所有的充值项,下载其中的商品图标和角标 | |||
for k, rechargeInfo in pairs(self.shopData) do | |||
if tonumber(selecttype) == rechargeInfo.type then | |||
-- 记录商品图标在本地保存的文件名 | |||
rechargeInfo.iconFile = nil | |||
if rechargeInfo.icon and rechargeInfo.icon ~= "" then | |||
rechargeInfo.iconFile = checkIcon(rechargeInfo.id, rechargeInfo.icon) | |||
end | |||
-- 记录商品角标在本地保存的文件名 | |||
rechargeInfo.privilegeFile = nil | |||
if rechargeInfo.privilege_icon and rechargeInfo.privilege_icon ~= "" then | |||
rechargeInfo.privilegeFile = checkIcon(rechargeInfo.id, rechargeInfo.privilege_icon) | |||
end | |||
-- 记录商品缩略图在本地保存的文件名 | |||
rechargeInfo.thumbFile = nil | |||
if rechargeInfo.ext and rechargeInfo.ext.thumb and rechargeInfo.ext.thumb ~= "" then | |||
rechargeInfo.thumbFile = checkIcon(rechargeInfo.prop_id, rechargeInfo.ext.thumb) | |||
end | |||
end | |||
end | |||
end | |||
return ProtocolPhpShop |
@@ -0,0 +1,294 @@ | |||
local RoomCmd = { | |||
--[[/** | |||
* 客户端通过协议0x8060通知server, 用户信息改变 | |||
* <pre> | |||
* 推送: {@code ClientChangeUserInfo} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_CLIENT_CHANGE_USERINFO = 0x8060, | |||
--[[/** | |||
* server收到0x8060协议后,广播当前桌子上所有用户 | |||
* <pre> | |||
* 推送: {@code ServerChangeUserInfo} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_SERVER_CHANGE_USERINFO = 0x8061, | |||
--[[/** | |||
* server收到0x8018协议后,广播当前桌子上所有用户 | |||
若小局结束后发现玩家红花数不足,系统则会自动解散此牌局,解散前服务器广播每个玩家 解散的具体的原因 | |||
* <pre> | |||
* 推送: {@code RedFlowerDismiss} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_RED_FLOWER_DISMISS = 0x8018, | |||
--[[/** | |||
* 洗牌协议 | |||
* <pre> | |||
* 推送: {@code } | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_XIPAI = 0x8062, | |||
--[[/** | |||
* 游戏结束后,服务器判断大赢家是否满足赠送条件,满足赠送条件的用户将会收到协议 | |||
* <pre> | |||
* 推送: {@code ChouJiangBroad} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_CHOUJIANG = 0x800a, | |||
} | |||
--* server收到0x8018协议后,广播当前桌子上所有用户 | |||
local ChouJiangBroad = defClass("ChouJiangBroad" | |||
--赠送产生的唯一标识,客户端拿到传给php领奖 | |||
, defVar("rewardToken", VT_String, "") | |||
--玩家剩余的积分 | |||
, defVar("leftMatchScore", VT_Int, 0) | |||
--需要支付的积分 | |||
, defVar("useScore", VT_Int, 0) | |||
--[[奖励格式json串,内容: | |||
{"prize":[" | |||
{\"idx\":4,\"type\":13,\"val\":0}", | |||
"{\"idx\":5,\"type\":13,\"val\":0}", | |||
"{\"idx\":1,\"type\":13,\"val\":0}", | |||
"{\"idx\":2,\"type\":13,\"val\":0}", | |||
"{\"idx\":3,\"type\":13,\"val\":0}" | |||
]} | |||
idx表示序号,type表示奖励类型,13表示房卡,1表示金币 val对应奖励的数值 | |||
]] | |||
, defVar("rewardInfo", VT_String, "") | |||
) | |||
--* server收到0x8018协议后,广播当前桌子上所有用户 | |||
local RedFlowerDismiss = defClass("RedFlowerDismiss" | |||
--更新信息的用户uid | |||
, defVar("retCode", VT_Short, 0) | |||
) | |||
--server收到0x8060协议后,广播当前桌子上所有用户 | |||
local ServerChangeUserInfo = defClass("ServerChangeUserInfo" | |||
--更新信息的用户uid | |||
, defVar("uid", VT_Int, -1) | |||
--用户信息 | |||
, defVar("userInfo", VT_String, "") | |||
--保留字段,暂不使用 | |||
, defVar("reserved", VT_String, "") | |||
) | |||
local RoomBase = class("RoomBase" , require("luaScript.Protocol.Protocol")) | |||
local matchErrorTip = { | |||
[1] = "超时停止游戏", | |||
[2] = "群主解散", | |||
[3] = "房卡不足", | |||
[4] = "系统解散", | |||
[5] = "桌子上有玩家红花数不足,房间自动解散!", | |||
} | |||
function RoomBase:ctor(net) | |||
RoomBase.super.ctor(self , net); | |||
-- 清空大结算抽奖数据,可能由于某些原因, | |||
-- 导致大结算没弹框或者消息延迟收到有数据缓存 | |||
dd.IGameOverAward.setAwardData(nil) | |||
self:initBindEvent() | |||
end | |||
function RoomBase:initBindEvent() | |||
self:defPushMsg{cmd = RoomCmd.GAME_COMMAND_SERVER_CHANGE_USERINFO, reader = ServerChangeUserInfo, func = handler(self , self.onGpsChangeResponse)} | |||
self:defPushMsg{cmd = RoomCmd.GAME_COMMAND_RED_FLOWER_DISMISS, reader = RedFlowerDismiss, func = handler(self , self.onRedFlowerDismiss)} | |||
self:defPushMsg{cmd = RoomCmd.GAME_COMMAND_XIPAI, reader = BytePacket, func = handler(self , self.onGameXiPai)} | |||
self:defPushMsg{cmd = RoomCmd.GAME_COMMAND_CHOUJIANG, reader = ChouJiangBroad, func = handler(self , self.onChouJiangBroad)} | |||
end | |||
-- 通知服务器玩家GPS数据发生变化 | |||
function RoomBase:requestGpsChange() | |||
local request = StringPacket:new() | |||
request.stringValue = app.user.userInfo or "" | |||
logD("RoomBase:requestGpsChange()", table.tostring(request)) | |||
self:sendResponse{cmd = RoomCmd.GAME_COMMAND_CLIENT_CHANGE_USERINFO , sender = request}; | |||
end | |||
-- 服务器下发玩家GPS数据发生变化 | |||
function RoomBase:onGpsChangeResponse(status, response) | |||
print("RoomBase:onGpsChangeResponse()", table.tostring(response)) | |||
--[[ | |||
--server收到0x8060协议后,广播当前桌子上所有用户 | |||
ServerChangeUserInfo = defClass("ServerChangeUserInfo" | |||
--更新信息的用户uid | |||
, defVar("uid", VT_Int, -1) | |||
--用户信息 | |||
, defVar("userInfo", VT_String, "") | |||
--保留字段,暂不使用 | |||
, defVar("reserved", VT_String, "") | |||
) | |||
--]] | |||
-- print("RoomBase:onGpsChangeResponse()", table.tostring(response)) | |||
local nUserId = response.uid | |||
local memberInfo = self.roomInfo and self.roomInfo.memberList and self.roomInfo.memberList[nUserId] | |||
if memberInfo then | |||
memberInfo.userInfo = response.userInfo | |||
end | |||
self:updateGpsUserInfo(nUserId) | |||
end | |||
function RoomBase:onRedFlowerDismiss(status, response) | |||
print("RoomBase:onRedFlowerDismiss()", table.tostring(response)) | |||
local code = response.retCode | |||
if code then | |||
self.roomInfo.isRedFlowerDismiss = true | |||
local retCode = matchErrorTip[code] or "errcode【"..code.."】不存在!" | |||
if code == 5 then | |||
retCode = "桌子上有玩家排名分不足,房间自动解散!" | |||
end | |||
showConfirmDialog(retCode) | |||
end | |||
end | |||
--更新gps用户数据 | |||
--需要检测的ID 没有则检测所有人的距离 | |||
--isOpenView 危险距离是否主动弹出提示 | |||
function RoomBase:updateGpsUserInfo(userId,isOpenView) | |||
if self.roomInfo and self.roomInfo.memberList then | |||
local isGameStart = self.roomInfo.nGameStartCount>0 | |||
local userInfoList = {} | |||
for nUserId, memberInfo in pairs(self.roomInfo.memberList) do | |||
local nSeatId = memberInfo.nSeatId | |||
local userInfo = memberInfo.userInfo | |||
userInfoList[nUserId] = {nSeatId = nSeatId, userInfo = userInfo} | |||
end | |||
if isGameStart then | |||
isOpenView = false | |||
end | |||
self:dispatchEvent({ | |||
name = GAME_EVENT.GPS_UPDATE_USER_INFO, | |||
userId=userId, | |||
userInfoList = userInfoList, | |||
isOpenView = isOpenView or false, | |||
isGameStart = isGameStart, | |||
-- maxPlayerNum = self.roomInfo.nMaxPlayCount, | |||
}) | |||
end | |||
end | |||
--检测本地gps信息跟服务器数据是否一致,不一致则发送更新 | |||
function RoomBase:checkGpsIsNew() | |||
if self.roomInfo and self.roomInfo.memberList then | |||
local myUserId = app.room:getMyUserId() or app.user.loginInfo.uid | |||
local user = self.roomInfo.memberList[myUserId] | |||
if user then | |||
local userInfo = json.decode(user.userInfo or "") | |||
if userInfo then | |||
local isNewest = app.user:isGpsInfoNewest(userInfo.gpsInfo) | |||
--不是最新的数据则发送给服务器同步 | |||
if not isNewest then | |||
app.room:requestGpsChange() | |||
return false | |||
end | |||
end | |||
end | |||
end | |||
return true | |||
end | |||
-- 通过玩家逻辑椅子号找到玩家ID | |||
function RoomBase:getUserIdBySeatId(nSeatId) | |||
return 0 | |||
end | |||
-- 通过玩家视图椅子号找到玩家ID | |||
function RoomBase:getUserIdByViewId(nViewId) | |||
return nil | |||
end | |||
-- 通过玩家ID获取玩家展示的座位号 | |||
function RoomBase:getViewIdByUserId(nUserId) | |||
return 1 | |||
end | |||
-- 通过玩家逻辑椅子号找到视图椅子号 | |||
function RoomBase:getViewIdBySeatId(nSeatId) | |||
return 1 | |||
end | |||
-- 通过玩家ID找到逻辑椅子号 | |||
function RoomBase:getSeatIdByUserId(nViewId) | |||
return 1 | |||
end | |||
-- 通过玩家视图椅子号找到逻辑椅子号 | |||
function RoomBase:getSeatIdByViewId(nUserId) | |||
return 1 | |||
end | |||
-- 获取房间内的用户信息 | |||
function RoomBase:getUserInfo(uid) | |||
return "" | |||
end | |||
function RoomBase:getMyUserId() | |||
if self:isInMemberList() then | |||
return app.user.loginInfo.uid | |||
else | |||
if self.roomInfo and self.roomInfo.memberList then | |||
for nUserId,v in pairs(self.roomInfo.memberList) do | |||
return nUserId | |||
end | |||
else | |||
return app.user.loginInfo.uid | |||
end | |||
end | |||
end | |||
function RoomBase:isInMemberList() | |||
if self.roomInfo and self.roomInfo.memberList then | |||
for nUserId,v in pairs (self.roomInfo.memberList) do | |||
if app.user.loginInfo.uid==nUserId then | |||
return true | |||
end | |||
end | |||
end | |||
return false | |||
end | |||
function RoomBase:sendGameXiPai() | |||
self:sendResponse{cmd = RoomCmd.GAME_COMMAND_XIPAI}; | |||
end | |||
-- 洗牌结果 | |||
function RoomBase:onGameXiPai(status, response) | |||
print("RoomBase:onGameXiPai()", table.tostring(response)) | |||
local result = response.byteValue | |||
if result == 3 then | |||
showTooltip("房卡不足") | |||
elseif result == 2 then | |||
showTooltip("已设置洗牌") | |||
elseif result == 1 then | |||
showTooltip("桌子状态未在小局结束") | |||
elseif result == 0 then | |||
app.user.loginInfo.curCardNum = app.user.loginInfo.curCardNum - 2 | |||
end | |||
end | |||
-- 抽奖结果 | |||
function RoomBase:onChouJiangBroad(status, response) | |||
logD("RoomBase:onChouJiangBroad()", table.tostring(response)) | |||
dd.IGameOverAward.setAwardData(response) | |||
end | |||
return RoomBase; |
@@ -0,0 +1,941 @@ | |||
--[[ | |||
说明:从服务器获取的所有配置信息 | |||
更新记录: | |||
------------------------------------------------------------------ | |||
2018-03-01 重新优化获取子游戏列表的流程 | |||
获取服务器配置成功之后,开始初始化子游戏列表,同时请求登录。 | |||
也就是说,登录时可以子游戏列表的数据可能是空的。 | |||
初始化子游戏列表的流程 | |||
1、从本地读取子游戏列表数据 | |||
2、从服务器获取子游戏列表数据,成功后覆盖本地数据 | |||
3、将子游戏列表数据写入到本地文件 | |||
玩家登陆成功需要显示游戏列表时,肯定是又数据的。 | |||
如果此时网络状况良好,则数据是服务器下发的最新数据, | |||
如果此时网络状况差,则使用的是本地文件的数据,即上一次从服务器获取的数据。 | |||
加入玩家是第一次打开游戏,就碰到网络状况差,则游戏列表是空的。此题无解。 | |||
------------------------------------------------------------------ | |||
--]] | |||
require("luaScript.Protocol.ProtocolCommon") | |||
local ServerConfigs = class("ServerConfigs", require("luaScript.Protocol.Protocol")) | |||
local ConfigCmd = | |||
{ | |||
--[[/** | |||
* 客户端请求获取配置信息 | |||
* <pre> | |||
* 请求: {@code ServerConfigRequest} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_GET_SERVER_CONF = 0x0301, | |||
--[[/** | |||
* server返回游戏的配置信息 | |||
* <pre> | |||
* 推送: {@code ServerConfigResponse} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_SEND_SERVER_CONF = 0x0302, | |||
--[[/** | |||
* server返回游戏的配置信息 | |||
* <pre> | |||
* 推送: {@code ServerConfigsResponse} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_SEND_GAME_CONF = 0x0303, | |||
--[[/** | |||
* 客户端和PHP之间交互使用的TCP通道 | |||
* <pre> | |||
* 请求: {@code StringPacket} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_PHP = 0x0401, | |||
} | |||
-- 登陆之前配置请求 | |||
ServerConfigRequest = defClass("ServerConfigRequest" | |||
-- gameId | |||
,defVar("appId", VT_String, "") | |||
) | |||
-- 服务器返回配置 | |||
ServerConfigResponse= defClass("ServerConfigResponse" | |||
--json格式的信息 | |||
, defVar("strContent", VT_String, "") | |||
) | |||
-- 多游戏配置数据 | |||
ServerConfigsResponse = defClass("ServerConfigsResponse" | |||
-- 各个游戏的配置信息,json格式, | |||
, defVar("gameServerConfigList", VT_Vector(VT_String), {}) | |||
) | |||
-- 登录之前需要做的初始化 | |||
function ServerConfigs:initBeforeLogin() | |||
if not self._isInited then | |||
self:requestGetServerConfig() | |||
end | |||
end | |||
function ServerConfigs:initBeforLoginSuccessed(bInit) | |||
self._isInited = (bInit == true) | |||
if self._isInited then | |||
self:dispatchEvent({name = "initBeforLoginSuccessed"}) | |||
end | |||
end | |||
function ServerConfigs:getInitStatus() | |||
return (self._isInited == true) | |||
end | |||
------------------------- PHP 通道 ------------------------- | |||
-- ttInfo : 传送给PHP的数据 | |||
-- callback : 处理后的回调 | |||
function ServerConfigs:sendPhpMsg(ttInfo, callback) | |||
if not ttInfo or type(ttInfo) ~= "table" then | |||
return | |||
end | |||
-- 索引++ | |||
self.phpIndex = self.phpIndex + 1; | |||
-- 记录回调索引 | |||
local callbackKey = self.phpIndex .. "_" .. (ttInfo.pSSq or "0") | |||
self.phpCallbackList[callbackKey] = callback | |||
-- 改变发往服务器的索引 | |||
ttInfo.pSSq = callbackKey | |||
local strContent = json.encode(ttInfo) | |||
-- 发送消息到服务器 | |||
local request = StringPacket:new() | |||
request.stringValue = strContent; | |||
logD("ServerConfigs:sendPhpMsg() request = " .. table.tostring(request)) | |||
self:sendResponse{cmd = ConfigCmd.GAME_COMMAND_PHP , sender = request}; | |||
end | |||
function ServerConfigs:onPhpMsgResponse(status, response) | |||
logD("ServerConfigs:onPhpMsgResponse()", tostring(status), table.tostring(response)) | |||
if status ~= 0 then | |||
return | |||
end | |||
local ttResult = json.decode(response.stringValue) | |||
if not ttResult then | |||
return | |||
end | |||
local index = tostring(ttResult.pSSq) | |||
if not index then | |||
return | |||
end | |||
if not self.phpCallbackList[index] then | |||
return | |||
end | |||
self.phpCallbackList[index](0, ttResult); | |||
self.phpCallbackList[index] = nil; | |||
end | |||
------------------------- 配置相关 ------------------------- | |||
-- 获取配置信息 | |||
function ServerConfigs:requestGetServerConfig() | |||
local request = ServerConfigRequest:new() | |||
request.appId = getAppId() | |||
log("ServerConfigs:requestGetServerConfig() request = ", table.tostring(request)) | |||
self:sendResponse{cmd = ConfigCmd.GAME_COMMAND_GET_SERVER_CONF , sender = request}; | |||
end | |||
function ServerConfigs:onServerConfigResponse(status, response) | |||
logD("ServerConfigs:onServerConfigResponse()", tostring(status), table.tostring(response)) | |||
if status ~= 0 then | |||
return | |||
end | |||
local ttResult = json.decode(response.strContent) | |||
-- 公告信息 | |||
self.notice = {} | |||
local notice = tostring(ttResult.notice) or "" | |||
if notice ~= "" then | |||
local arr = string.split(notice, "\n") | |||
for k,v in pairs(arr) do | |||
table.insert(self.notice, v) | |||
end | |||
end | |||
-- 滚动公告 | |||
self.scroll = tostring(ttResult.scroll) or "" | |||
-- 游戏ID | |||
self.gameId = tonumber(ttResult.gameId) or 0 | |||
-- 区域信息 | |||
self.areano = tonumber(ttResult.areano) or 0 | |||
-- 记录获取大厅配置成功 | |||
self.isGetConfigSuccess = true | |||
self:onServerConfigSuccessed(); | |||
end | |||
function ServerConfigs:onServerConfigsResponse(status, response) | |||
log("ServerConfigs:onServerConfigsResponse()", tostring(status), table.tostring(response)) | |||
if status ~= 0 then | |||
return | |||
end | |||
self.configs = {} | |||
for _, value in pairs(response.gameServerConfigList) do | |||
local ttConfig = json.decode(value) | |||
if ttConfig and type(ttConfig) == "table" and ttConfig.gameid then | |||
self.configs[tonumber(ttConfig.gameid)] = ttConfig; | |||
if ttConfig.contiTimer then--连打房间解散时间,黄十八用 | |||
app.user.contiTimer = ttConfig.contiTimer | |||
end | |||
end | |||
end | |||
self.isGetConfigsSuccess = true; | |||
self:onServerConfigSuccessed(); | |||
end | |||
function ServerConfigs:onServerConfigSuccessed() | |||
if self.isGetConfigSuccess and self.isGetConfigsSuccess then | |||
-- 先请求一次全国数据,亲友圈、创建房间、修改玩法里面显示的必须是所有游戏 | |||
self:requestGameList(0, true, function () | |||
-- 再根据当前选择地区,再拉取对应地区的游戏列表 | |||
local regionCode = cc.UserDefault:getInstance():getIntegerForKey("address_code_" .. app.config.RomSetting.Platform) | |||
self:requestGameList(regionCode) | |||
end) | |||
self:initBeforLoginSuccessed(true) | |||
end | |||
end | |||
------------------------- 子游戏列表 ------------------------- | |||
function ServerConfigs:saveSubGameListToFile() | |||
logD("ServerConfigs:saveSubGameListToFile()", table.tostring(self.subGameList)) | |||
table.saveToLocFile(self.subGameList, "SubGameList.lua") | |||
end | |||
function ServerConfigs:loadSubGameListFromFile() | |||
self.subGameList = table.loadFromLocFile("SubGameList.lua") or {} | |||
logD("ServerConfigs:loadSubGameListFromFile()", table.tostring(self.subGameList)) | |||
end | |||
-- 获取子游戏版本信息 | |||
function ServerConfigs:requestGetSubGameVersions(endCallback) | |||
local params = | |||
{ | |||
action = "system.games", | |||
app = getAppId(), | |||
uid = loadUserId(), | |||
apkver = "",-- 获取子游戏版本号时不再依赖APK的版本号 - zzb,20190715 | |||
installGameVer = "", | |||
isNew=1, | |||
} | |||
for gameId,v in pairs(self.subGameList) do | |||
local ver=app.subGameManager:isInstaller(gameId) and app.subGameManager.GameVersions[gameId] or -1 | |||
params.installGameVer=params.installGameVer..gameId..","..ver.."|" | |||
end | |||
--基础包 | |||
local baseIds={1001,1002,1003} | |||
for k,gameId in pairs(baseIds) do | |||
local ver=app.subGameManager:isInstaller(gameId) and app.subGameManager.GameVersions[gameId] or -1 | |||
params.installGameVer=params.installGameVer..gameId..","..ver.."|" | |||
end | |||
logD("ServerConfigs:requestGetSubGameVersions() ", table.tostring(params)); | |||
self:sendPhpMsg(params, function(status, response) | |||
self:getSubGameVersionsResponse(status, response) | |||
if endCallback then | |||
endCallback() | |||
end | |||
end) | |||
end | |||
function ServerConfigs:getSubGameVersionsResponse(status, ttResult) | |||
logD("ServerConfigs:getSubGameVersionsResponse() " .. table.tostring(ttResult)) | |||
self.getsubGameList = true | |||
if ttResult and tonumber(ttResult.code) == 200 and ttResult.result and type(ttResult.result) == "table" then | |||
for k,v in pairs(ttResult.result) do | |||
if k~="new" then | |||
local gameId = tonumber(k) | |||
local gameInfo = self.subGameList[gameId] or {} | |||
-- 下载提示 | |||
gameInfo.desc = tostring(v.desc) | |||
-- 新版本 | |||
gameInfo.version = tostring(v.ver) | |||
-- 资源下载地址 | |||
if v.url and v.url ~= "" then | |||
gameInfo.versionUrls = toStringArray(",")(v.url) | |||
end | |||
self.subGameList[gameId] = gameInfo; | |||
end | |||
end | |||
--添加新更新数据 | |||
if ttResult.result.new then | |||
for k,v in pairs(ttResult.result.new) do | |||
local gameId = tonumber(k) | |||
if self.subGameList[gameId] then | |||
self.subGameList[gameId].newUpdate=v | |||
else | |||
self.subGameList[gameId] = {} | |||
self.subGameList[gameId].newUpdate=v | |||
end | |||
end | |||
end | |||
end | |||
-- 添加更多游戏的显示 | |||
-- local gameInfo = | |||
-- { | |||
-- gameId = 0; | |||
-- gameName = "更多游戏"; | |||
-- sortIndex = 9999; | |||
-- show = true; | |||
-- } | |||
-- self.subGameList[gameInfo.gameId] = gameInfo | |||
if isIOSReviewVersion() then | |||
-- 苹果审核 | |||
---self:updateSubGameVisible({7,12}) | |||
self:updateSubGameVisible() | |||
elseif isRuanZhu() then | |||
-- 软著 | |||
if app.config.RomSetting.ruanZhuGames then | |||
self:updateSubGameVisible(app.config.RomSetting.ruanZhuGames or {}) | |||
else | |||
-- 六胡抢 | |||
self:updateSubGameVisible({5}) | |||
end | |||
else | |||
--self:updateSubGameVisible() | |||
--logD("ServerConfigs requestGameList4 :", table.tostring(self.subGameList)) | |||
if self.subGameList[3] then --欢乐拼五张 | |||
self.subGameList[3].show = false | |||
end | |||
end | |||
-- 保存到本地 | |||
self:saveSubGameListToFile(); | |||
self:dispatchEvent({name = "getSubGameListSuccessed"}) | |||
end | |||
-- 设置哪些子游戏是需要显示的 | |||
-- ttShow = {gameid, gameid, gameid} | |||
function ServerConfigs:updateSubGameVisible(ttShow) | |||
if ttShow then | |||
-- 全部标记为不显示 | |||
for k,v in pairs(self.subGameList) do | |||
v.show = false; | |||
end | |||
for _,v in pairs(ttShow) do | |||
if self.subGameList[v] then | |||
self.subGameList[v].show = true | |||
end | |||
end | |||
else | |||
-- 全部标记为显示 | |||
for k,v in pairs(self.subGameList) do | |||
v.show = true; | |||
end | |||
end | |||
end | |||
-- 获取指定子游戏的配置信息 | |||
-- 可能返回 nil | |||
function ServerConfigs:getSubGameConfig(gameId) | |||
if not gameId then | |||
return nil | |||
end | |||
return self.subGameList[gameId] | |||
end | |||
-- 获取指定web子游戏的配置信息 | |||
-- 可能返回 nil | |||
function ServerConfigs:getWebGameConfig(gameId) | |||
for i,v in pairs(self.webGameList) do | |||
if v.gameId == gameId then | |||
return v | |||
end | |||
end | |||
return nil | |||
end | |||
function ServerConfigs:requestClientConfig(callback) | |||
logD("ServerConfigs:requestClientConfig()") | |||
local params = | |||
{ | |||
action = "system.clicfg", | |||
app = getAppId(), | |||
uid = loadUserId(), | |||
} | |||
logD("ServerConfigs:requestClientConfig() ", table.tostring(params)); | |||
app.waitDialogManager:showWaitNetworkDialog("请稍等...") | |||
self:sendPhpMsg(params, function(status,response) | |||
app.waitDialogManager:closeWaitNetworkDialog() | |||
logD("ServerConfigs:requestClientConfig() ", table.tostring(response)); | |||
if tonumber(response.code)==200 then | |||
if response.result and table.nums(response.result)>0 then | |||
self.clientConfig = response.result | |||
table.saveToLocFile(self.clientConfig, "ClientConfig.lua") | |||
math.randomseed(tostring(os.time()):reverse():sub(1, 6)); | |||
local wx = response.result.wx or {}; | |||
if table.nums(wx) > 0 then | |||
local idx = math.random(table.nums(wx)) | |||
if wx[idx] then | |||
app.plugin:initWxShare(wx[idx].appid, wx[idx].secret); | |||
else | |||
app.plugin:initWxShare(wx.appid, wx.secret); | |||
end | |||
else | |||
if app.plugin and wx.appid and wx.secret then | |||
app.plugin:initWxShare(wx.appid, wx.secret); | |||
end | |||
end | |||
end | |||
end | |||
if callback then callback() end | |||
app:dispatchEvent({name = "onRequestClientConfig"}) | |||
end) | |||
end | |||
function ServerConfigs:requestWebGameUrl(gameId,callback) | |||
local function getOrientation (url) | |||
local orientation = 1; | |||
local index = string.find(url,"?") | |||
if index then | |||
local params=string.sub(url,index+1,string.len(url)) | |||
local tmp = string.split(params,"&"); | |||
local args = {}; | |||
for k, v in pairs(tmp) do | |||
local arr = string.split(v, "="); | |||
if arr[1] == "orientation" then | |||
orientation = arr[2] or 1; | |||
break; | |||
end | |||
end | |||
end | |||
return orientation; | |||
end | |||
local params = | |||
{ | |||
action = "platform.geturl", | |||
app = getAppId(), | |||
uid = loadUserId(), | |||
tinyid = gameId, | |||
} | |||
-- logD("ProtocolSubGame:requestWebGameList() ", table.tostring(params)); | |||
self:sendPhpMsg(params,function (status,response) | |||
-- dump(response) | |||
if tonumber(response.code)==200 then | |||
local orientation = getOrientation(response.result); | |||
if callback then callback(response.result, tonumber(orientation)) end | |||
else | |||
if callback then callback() end | |||
end | |||
end) | |||
end | |||
function ServerConfigs:getGameGroupConfig(gameId, regionCode) | |||
regionCode = regionCode or 0 | |||
local subGameList = self.regionGameList[regionCode] or self.subGameList | |||
if subGameList[gameId] then | |||
local strGameConfig = subGameList[gameId].gameRule | |||
if strGameConfig and strGameConfig~="" then | |||
local gameConfig = json.decode(strGameConfig) | |||
if gameConfig and gameConfig.group and gameConfig.group.games then | |||
return gameConfig.group | |||
end | |||
end | |||
end | |||
return nil | |||
end | |||
function ServerConfigs:getWebGameGroupConfig(gameId) | |||
for i,v in pairs(self.webGameList) do | |||
if v.gameId == gameId then | |||
local strGameConfig = v.gamecfg | |||
if strGameConfig and strGameConfig~="" then | |||
local gameConfig = json.decode(strGameConfig) | |||
if gameConfig and gameConfig.group then | |||
return gameConfig.group | |||
end | |||
end | |||
end | |||
end | |||
return nil | |||
end | |||
--- | |||
-- 子游戏是否在合集里面 | |||
-- @return boolean | |||
-- | |||
function ServerConfigs:isWebGameInGroup (gameId) | |||
local isExist = false | |||
for i,v in pairs(self.webGameList) do | |||
local groupConfig = self:getWebGameGroupConfig(v.gameId) or {} | |||
local games = groupConfig.games or {} | |||
for _, id in ipairs(games) do | |||
if tonumber(id) == tonumber(gameId) then | |||
isExist = true | |||
break | |||
end | |||
end | |||
if isExist then | |||
break | |||
end | |||
end | |||
return isExist | |||
end | |||
function ServerConfigs:isNewGame(gameId) | |||
if self.subGameList[gameId] then | |||
local strGameConfig = self.subGameList[gameId].gameRule | |||
if strGameConfig and strGameConfig~="" then | |||
local gameConfig = json.decode(strGameConfig) | |||
if gameConfig and gameConfig.isNew then | |||
return gameConfig.isNew | |||
end | |||
end | |||
end | |||
return false | |||
end | |||
--- | |||
-- 获取子游戏列表 | |||
-- @return | |||
-- | |||
function ServerConfigs:getSubGameList() | |||
return self.subGameList | |||
end | |||
--- | |||
-- 获取子游戏列表(没有子游戏具体信息) | |||
-- @return | |||
-- | |||
function ServerConfigs:getGameList(regionCode) | |||
regionCode = regionCode or 0 | |||
local gameList = {} | |||
local baseIds={ | |||
[1001]=true, | |||
[1002]=true, | |||
[1003]=true | |||
} | |||
if isIOSReviewVersion() then | |||
-- 添加更多游戏的显示 | |||
local gameInfo = | |||
{ | |||
gameId = 0; | |||
gameName = "更多游戏"; | |||
sortIndex = 9999; | |||
show = true; | |||
visible = true; | |||
} | |||
self.subGameList[gameInfo.gameId] = gameInfo | |||
end | |||
local subGameList = self.regionGameList[regionCode] or self.subGameList | |||
local tt = {} | |||
for k,v in pairs(subGameList) do | |||
if v.visible and v.showInHall == 1 then | |||
if v.other_name and v.other_name ~= "" then | |||
if not tt[v.other_name] then | |||
tt[v.other_name] = {} | |||
end | |||
table.insert(tt[v.other_name],{gameId = v.gameId, sort = v.sortIndex ,gameType = "sub"}) | |||
elseif v.gameId and not baseIds[v.gameId] then | |||
table.insert(gameList,{gameId = v.gameId, sort = v.sortIndex ,gameType = "sub"}) | |||
end | |||
end | |||
end | |||
for k,v in pairs(tt) do | |||
--求最小排序 | |||
table.sort(v, function (a,b) | |||
return a.sort<b.sort | |||
end) | |||
table.insert(gameList,{data = v,sort = v[1].sort,gameType = "sub",gameId = v[1].gameId}) | |||
end | |||
--如果是苹果审核版则不需要小游戏 | |||
if not isIOSReviewVersion() then | |||
local ttWebGame = {} | |||
for k,v in pairs(self.webGameList) do | |||
if v.other_name and v.other_name ~= "" then | |||
if not tt[v.other_name] then | |||
tt[v.other_name] = {} | |||
end | |||
table.insert(tt[v.other_name],{gameId = v.gameId, sort = v.sortIndex ,gameType = "web"}) | |||
else | |||
table.insert(gameList,{gameId = v.gameId, icon = v.icon, sort = v.sort ,gameType = "web"}) | |||
end | |||
end | |||
for k,v in pairs(ttWebGame) do | |||
table.insert(gameList,{data = v,sort = v[1].sort,gameType = "web",gameId = v[1].gameId}) | |||
end | |||
end | |||
table.sort(gameList, function (a,b) | |||
return a.sort<b.sort | |||
end) | |||
dump(gameList,"--hall gamelist--") | |||
return gameList | |||
end | |||
--是否对当前用户打开webGame | |||
function ServerConfigs:isOpenWebGame(gameId) | |||
local isOpen = false | |||
local gamecfg = nil | |||
for k,v in pairs(self.webGameList) do | |||
if v.gameId==gameId then | |||
gamecfg = v.gamecfg | |||
break | |||
end | |||
end | |||
-- local gamecfg = webGame.gamecfg --添加userid 字段判断白名单测试 | |||
if gamecfg and gamecfg~="" then | |||
local cfg = json.decode(gamecfg) | |||
if cfg and cfg.userId then | |||
local users = string.split(cfg.userId,",") | |||
for k,v in pairs(users) do | |||
if tonumber(v) == tonumber(app.user.loginInfo.uid) then | |||
isOpen = true | |||
end | |||
end | |||
else | |||
isOpen = true | |||
end | |||
else | |||
isOpen = true | |||
end | |||
return isOpen | |||
end | |||
function ServerConfigs:isNewWebGame(gameId) | |||
local isNew = false | |||
local gamecfg = nil | |||
for k,v in pairs(self.webGameList) do | |||
if v.gameId==gameId then | |||
gamecfg = v.gamecfg | |||
break | |||
end | |||
end | |||
-- local gamecfg = webGame.gamecfg --添加userid 字段判断白名单测试 | |||
if gamecfg and gamecfg~="" then | |||
local cfg = json.decode(gamecfg) | |||
if cfg and cfg.isNew then | |||
isNew = cfg.isNew | |||
end | |||
end | |||
return isNew | |||
end | |||
--获取活动数据列表(新接口) | |||
function ServerConfigs:requestMissionList() | |||
local params = | |||
{ | |||
action= "missions.lists", | |||
uid = app.user.loginInfo.uid, | |||
app = getAppId(), | |||
} | |||
logD("ServerConfigs:requestMissionList()", table.tostring(params)) | |||
self:sendPhpMsg(params, function(status,response) | |||
-- if status ~= "successed" then | |||
-- logE("活动数据拉取失败") | |||
-- return | |||
-- end | |||
-- local data = json.decode(response) | |||
-- logD("ServerConfigs:requestMissionList()", table.tostring(response)) | |||
if tonumber(response.code)~=200 then | |||
logE("活动数据错误") | |||
return | |||
end | |||
-- "code":200, | |||
-- "error":"", | |||
-- "result":{ | |||
-- { | |||
-- "id" : 1, //任务ID | |||
-- "type": 1, //任务类型 4展示任务 | |||
-- "name":"活动名称", //任务名称 | |||
-- "desc":"" //任务描述 | |||
-- "ishot": 1, //是否最热 | |||
-- "sort":1, //排序 | |||
-- "ext":'', //扩展信息 | |||
-- "pic":'', //图片 | |||
-- "catalog":1, //活动分类 1 游戏公告 2 精彩活动 | |||
-- } | |||
-- } | |||
self.missions = response.result or {} | |||
-- for k,v in pairs(data.result) do | |||
-- end | |||
app:dispatchEvent({name = "onGetActivityInfoResponse"}) | |||
end) | |||
end | |||
function ServerConfigs:getMissionListByType(catalog) | |||
local missions = {} | |||
local stickyIndex = 1 --置顶的index | |||
for k,v in pairs(self.missions) do | |||
if v.catalog == catalog then | |||
table.insert(missions,v) | |||
end | |||
--if v.sticky==1 then --置顶 | |||
-- stickyIndex = #missions | |||
--end | |||
end | |||
table.sort(missions,function(a,b) | |||
return a.sort<b.sort | |||
end) | |||
for k,v in pairs(missions) do | |||
if v.sticky==1 then --置顶 | |||
stickyIndex = k | |||
end | |||
end | |||
return missions,stickyIndex | |||
end | |||
--获取置顶类型 | |||
function ServerConfigs:getStickyType() | |||
local catalog = 1 --置顶的类型 | |||
for k,v in pairs(self.missions) do | |||
if v.sticky==1 then --置顶 | |||
catalog = v.catalog | |||
end | |||
end | |||
return catalog | |||
end | |||
function ServerConfigs:popConfig() | |||
self:initPopConfig() | |||
if self.popConfigs and #self.popConfigs>0 then | |||
local config = self.popConfigs[1] | |||
table.remove(self.popConfigs,1) | |||
return config | |||
end | |||
return nil | |||
end | |||
function ServerConfigs:initPopConfig() | |||
if self.popConfigs then | |||
return | |||
end | |||
--弹出配置 | |||
if cc.Application:getInstance():getTargetPlatform() == 0 then | |||
-- self.popConfigs = {"luaScript.Views.Main.HongBaoKa.HongBaoKaView", "luaScript.Views.Activity.ActivityMainView"} | |||
self.popConfigs = {} | |||
else | |||
local popWindows = PhpSetting["pop_window"] or {} | |||
table.sort(popWindows, function (a, b) | |||
return a.index < b.index | |||
end) | |||
local configs = {} | |||
for _, v in ipairs(popWindows or {}) do | |||
if v then | |||
table.insert(configs, v.view) | |||
end | |||
end | |||
self.popConfigs = configs; | |||
end | |||
end | |||
function ServerConfigs:ctor(net) | |||
ServerConfigs.super.ctor(self , net, ModuleId); | |||
-- php 通道相关 | |||
self.phpIndex = 0 | |||
self.phpCallbackList = {}; | |||
self.isGetGameVerList = false | |||
-- 大厅的配置信息 | |||
self.notice = {}; --{"",""} | |||
self.scroll = ""; -- | |||
self.areano = ""; -- | |||
-- 从gameServer获取的游戏列表 | |||
self.configs = {} | |||
--活动配置 | |||
self.missions = {} | |||
-- 从php获取的游戏列表 | |||
--[[ self.subGameList = | |||
{ | |||
[gameid] = | |||
{ | |||
show = true; | |||
gameId = 5; | |||
gameName = "六胡抢"; | |||
gameIcon = "http://img.dingdingqipai.com/images/games/lhq.png?v=1515639314"; | |||
sortIndex = 4; | |||
version = "1000"; | |||
versionUrls = {url, url} | |||
}, | |||
} | |||
--]] | |||
self.subGameList = {} | |||
self.webGameList = table.loadFromLocFile("WebGameList.lua") or {} | |||
self.clientConfig = table.loadFromLocFile("ClientConfig.lua") or { | |||
myHead = "http://cnplayer.ddpenghu.com/client/user/loginpost?wechatid=8&wechatmpid=8", -- 我的装扮 | |||
webgamb = RomSetting.ZhanJiUrl, -- 网页战绩 | |||
} | |||
-- 是否已经初始化完成 | |||
self._isInited = false | |||
-- 默认读取本地信息 | |||
self:loadSubGameListFromFile() | |||
self:updateSubGameVisible() | |||
-- 请求配置信息 | |||
self:defPushMsg{cmd = ConfigCmd.GAME_COMMAND_SEND_SERVER_CONF, reader = ServerConfigResponse, func = handler(self , self.onServerConfigResponse)}; | |||
self:defPushMsg{cmd = ConfigCmd.GAME_COMMAND_SEND_GAME_CONF, reader = ServerConfigsResponse, func = handler(self , self.onServerConfigsResponse)}; | |||
-- PHP 通道 | |||
self:defPushMsg{cmd = ConfigCmd.GAME_COMMAND_PHP, reader = StringPacket, func = handler(self , self.onPhpMsgResponse)}; | |||
end | |||
-------------------------------------------------------------------------------------------------------------------------------- | |||
-------------------------------------------------------------------------------------------------------------------------------- | |||
-------------------------------------------------------------------------------------------------------------------------------- | |||
-------------------------------------------------------------------------------------------------------------------------------- | |||
function ServerConfigs:requestGameList(regionCode, isFirstRequest, callback) | |||
-- 保存所有地区的游戏列表数据 | |||
self.regionGameList = self.regionGameList or {} | |||
regionCode = regionCode or 0 | |||
if self.regionGameList[regionCode] then | |||
-- 如果已经请求过该地区的数据,则不再请求游戏列表 | |||
self:dispatchEvent({name = "getSubGameListSuccessed"}) | |||
app.waitDialogManager:closeWaitNetworkDialog() | |||
return | |||
end | |||
local params = | |||
{ | |||
action = "system.uniongameinfo", | |||
app = getAppId(), | |||
uid = loadUserId(), | |||
region = regionCode, | |||
} | |||
logD("ServerConfigs requestGameList :", table.tostring(params)) | |||
self:sendPhpMsg(params, function(status, response) | |||
logD("ServerConfigs requestGameList :", table.tostring(response)) | |||
app.waitDialogManager:closeWaitNetworkDialog() | |||
if tonumber(response.code) == 200 then | |||
-- self.subGameList = {} | |||
local subGameList = {} | |||
if response.result.game then | |||
for k,v in pairs(response.result.game) do | |||
local gameId = tonumber(k) | |||
local gamecfg = v.gamecfg | |||
local gamecfgData = json.decode(gamecfg) | |||
local gameInfo = {} | |||
-- gameId = gameId == 43 and 22 or gameId | |||
gameInfo.gameId = gameId | |||
gameInfo.gameName = tostring(v.name) | |||
gameInfo.gameIcon = tostring(v.icon) | |||
gameInfo.gameRule = tostring(v.gamecfg) | |||
gameInfo.sortIndex = tonumber(v.sort) | |||
gameInfo.other_name = tostring(v.other_name) | |||
gameInfo.show = true | |||
--游戏列表的显示逻辑用visible,创建房间的逻辑用show | |||
if gamecfgData then | |||
if gamecfgData.group and gamecfgData.group.show == "0" then | |||
gameInfo.visible = false | |||
else | |||
gameInfo.visible = true | |||
end | |||
if not gamecfgData.showInHall then | |||
gameInfo.showInHall = 1 | |||
else | |||
gameInfo.showInHall = tonumber(gamecfgData.showInHall) | |||
end | |||
else | |||
gameInfo.visible = true | |||
gameInfo.showInHall = 1 | |||
end | |||
-- self.subGameList[gameId] = gameInfo | |||
subGameList[gameId] = gameInfo | |||
end | |||
end | |||
-- 记录已经拉取过的地区游戏列表 | |||
self.regionGameList[regionCode] = subGameList | |||
if isFirstRequest then | |||
-- self.subGameList为所有的游戏列表,检测游戏是否存在、热更等使用这个self.subGameList | |||
-- 大厅主界面显示游戏列表,使用self.regionGameList[regionCode] | |||
self.subGameList = self.regionGameList[regionCode] | |||
end | |||
self.webGameList = {} | |||
if response.result.tiny then | |||
for gameId,v in pairs(response.result.tiny) do | |||
v.gameId = tonumber(gameId) | |||
local gamecfgData = json.decode(v.gamecfg) | |||
if gamecfgData then | |||
local uids = gamecfgData.uids | |||
local uid = app.user.loginInfo.uid | |||
if uids then | |||
for _, vv in pairs(uids) do | |||
if tonumber(vv) == uid then | |||
table.insert(self.webGameList, v) | |||
break | |||
end | |||
end | |||
else | |||
table.insert(self.webGameList, v) | |||
end | |||
else | |||
table.insert(self.webGameList, v) | |||
end | |||
end | |||
table.saveToLocFile(self.webGameList, "WebGameList.lua") | |||
end | |||
if isFirstRequest then | |||
-- 只有第一次拉取所有全国游戏列表的时候,才会拉取版本信息 | |||
self:requestGetSubGameVersions(callback) | |||
else | |||
self:dispatchEvent({name = "getSubGameListSuccessed"}) | |||
end | |||
end | |||
end) | |||
end | |||
return ServerConfigs |
@@ -0,0 +1,63 @@ | |||
require("luaScript.Protocol.ProtocolCommon") | |||
require("luaScript.GameTypeDef") | |||
local ProtocolSystemSetting = class("ProtocolSystemSetting") | |||
-- 系统设置 | |||
SystemSettingEntity = defClass("SystemSettingEntity" | |||
-- 开启声音 | |||
, defVar("sound", VT_Bool, true) | |||
-- 开启音乐 | |||
, defVar("music", VT_Bool, true) | |||
--音效音量[0-1] | |||
, defVar("soundVolume", VT_Float, 1.0) | |||
--音乐音量[0-1] | |||
, defVar("musicVolume", VT_Float, 1,0) | |||
-- 省点模式 | |||
, defVar("safePower", VT_Bool, false) | |||
-- 画面质量(0低质量,1高质量) | |||
, defVar("graphicQuality", VT_Int, 1) | |||
-- 视图类型 2D 3D | |||
, defVar("viewType", VT_String, "2d") | |||
) | |||
SystemSettingEntity:setVersion(1); | |||
local ReadedFilePath = cc.FileUtils:getInstance():getWritablePath() .. "SystemSetting.data"; | |||
local effectData = true | |||
-- 保存 | |||
function ProtocolSystemSetting:save() | |||
effectData = self.info.sound | |||
SystemSettingEntity:saveToFile(self.info , ReadedFilePath); | |||
end | |||
-- 加载 | |||
function ProtocolSystemSetting:load() | |||
local function loadFromFile() | |||
local data = SystemSettingEntity:loadFromFile(ReadedFilePath); | |||
if data then | |||
self.info = data; | |||
effectData = self.info.sound | |||
print("aaaaaaaa:"..table.tostring(data)) | |||
else | |||
self.info = SystemSettingEntity:new(); | |||
end | |||
end | |||
-- 容错处理 | |||
xpcall(loadFromFile , function()self.info = SystemSettingEntity:new();end); | |||
end | |||
-- 恢复默认 | |||
function ProtocolSystemSetting:restore() | |||
self.info = SystemSettingEntity:new():updateTo(self.info); | |||
end | |||
--重置音效 | |||
function ProtocolSystemSetting:resetEffect() | |||
self.info.sound = effectData | |||
end | |||
function ProtocolSystemSetting:ctor() | |||
self.info = nil; | |||
self:load(); | |||
end | |||
return ProtocolSystemSetting; |
@@ -0,0 +1,718 @@ | |||
require("luaScript.Protocol.ProtocolCommon") | |||
local User = class("User" , require("luaScript.Protocol.Protocol")) | |||
-- 命令集合 | |||
local UserCmd = { | |||
--[[/** | |||
* 请求登录 | |||
* <pre> | |||
* 请求: {@code LoginRequest} | |||
* 返回:{@code LoginResponse} | |||
* </pre> | |||
*/--]] | |||
LoginRequest = 0x0001; | |||
--[[/** | |||
* 登录返回结果 | |||
* <pre> | |||
* 推送: {@code LoginResponse} | |||
* </pre> | |||
*/--]] | |||
LoginResponse = 0x0002; | |||
--[[/** | |||
* 手机号码登录错误信息 | |||
* <pre> | |||
* 推送: {@code PhoneLoginErrResponse} | |||
* </pre> | |||
*/--]] | |||
PhoneLoginErrResponse = 0x0003; | |||
--[[/** | |||
* 绑定手机,微信,二次授权 | |||
* <pre> | |||
* 推送: {@code PhoneBindRequest} | |||
* </pre> | |||
*/--]] | |||
PhoneBindRequest = 0x0020; | |||
--[[/** | |||
* 绑定手机,微信,二次授权结果 | |||
* <pre> | |||
* 推送: {@code PhoneBindResponse} | |||
* </pre> | |||
*/--]] | |||
PhoneBindResponse = 0x0021; | |||
--[[/** | |||
* 用一个账号同时登陆时,踢出最早登陆的设备 | |||
* <pre> | |||
* 推送: {@code IntPacket} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_CLIENT_KICT_MULTI_LOGIN = 0x0043; | |||
--[[/** | |||
* 聊天内容 | |||
* <pre> | |||
* 推送: {@code ChatMessageResponse} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_CHAT_MESSAGE = 0x8004, | |||
--[[/** | |||
* 修改手机号/忘记密码 | |||
* <pre> | |||
* 推送: {@code changePlayerInfoRequest} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_CHANGE_PLAYER_INFO = 0x0023; | |||
--[[/** | |||
* 修改手机号/忘记密码 | |||
* <pre> | |||
* 推送: {@code changePlayerInfoResponse} | |||
* </pre> | |||
*/--]] | |||
GAME_COMMAND_CHANGE_INFO_RESPONSE= 0x0024; | |||
} | |||
-- 登陆请求 | |||
LoginRequest = defClass("LoginRequest" | |||
-- 固定为0 | |||
, defVar("uid", VT_Int, 0) | |||
-- 微信登陆 openId | |||
, defVar("openId", VT_String, "") | |||
-- 微信登陆 unionId | |||
, defVar("unionId", VT_String, "") | |||
-- 微信登陆 weixinInfo | |||
, defVar("weixinInfo", VT_String, "") | |||
-- 用户登录方式 | |||
--0: 微信登录 | |||
--1: 手机密码登录。openId为对应的手机号,unionId为密码 | |||
--2: 手机验证码登录。openId为对应的手机号,unionId为验证码 | |||
, defVar("loginType", VT_Short, 0) | |||
-- 验证码 | |||
, defVar("checkcode", VT_String, "") | |||
) | |||
-- 登陆回复 | |||
LoginResponse = defClass("LoginResponse" | |||
-- 用户id, 根据openid 以及unionid映射得到 | |||
, defVar("uid", VT_Int, 0) | |||
-- 桌子id | |||
, defVar("tid", VT_Int, 0) | |||
-- 服务id | |||
, defVar("serverId", VT_Int, 0) | |||
-- 服务等级 | |||
, defVar("serverLevel", VT_Short, 0) | |||
-- 游戏id, 若上述tid 与gameid取值都不为0时,表示用户在游戏中 | |||
, defVar("gameId", VT_Short, 0) | |||
-- string格式, 目前只有roomCard信息(历史消耗房卡数量,当前房卡数量) | |||
, defVar("userInfo", VT_String, "") | |||
-- string格式, json数据,token,PHP登录使用 | |||
, defVar("jsonData", VT_String, "") | |||
-- byte matchFlag; //是否在比赛中0: 不在 1:在 | |||
, defVar("matchFlag", VT_Byte, "") | |||
-- 历史房卡数 | |||
, localVar("historyCardNum", VT_Int, "") | |||
-- 当前房卡数 | |||
, localVar("curCardNum", VT_Int, "") | |||
-- 当前悠闲豆 | |||
, localVar("curBeanNum", VT_Int, 0) | |||
-- 当前礼券 | |||
, localVar("curLiquanNum", VT_Int, 0) | |||
) | |||
-- 手机号码登录结果 | |||
PhoneLoginErrResponse = defClass("PhoneLoginErrResponse" | |||
-- 登录结果 | |||
-- 1、电话号码未绑定 | |||
-- 2、密码错误 | |||
-- 3、黑名单用户 | |||
-- 4、验证码错误 | |||
, defVar("ret", VT_Short, 0) | |||
) | |||
-- 绑定手机号码请求 | |||
PhoneBindRequest = defClass("PhoneBindRequest" | |||
-- 用户id | |||
, defVar("uid", VT_Int, 0) | |||
-- 绑定唯一标识 | |||
--, defVar("phonenum", VT_String, "") | |||
, defVar("account", VT_String, "") | |||
-- 密码 unionId | |||
, defVar("password", VT_String, "") | |||
-- 验证码 | |||
, defVar("checkcode", VT_Int, "") | |||
-- weixinInfo | |||
, defVar("weixinInfo", VT_String, "") | |||
-- 奖励类型:1. 房卡 2.金币 3. 活动房卡 4. RMB 5. 红包券 | |||
, defVar("rewardType", VT_Short, 0) | |||
-- 绑定类型 | |||
-- 0:手机绑定,account:手机号,weixinInfo 必须有值,3微信绑定 | |||
, defVar("bindType", VT_Short, 5) | |||
) | |||
-- 绑定手机号码结果 | |||
PhoneBindResponse = defClass("PhoneBindResponse" | |||
-- 0: 绑定成功 | |||
-- 1: 验证码错误 | |||
-- 2: 已绑定过手机号 | |||
-- 6:手机绑定此微信 | |||
, defVar("ret", VT_Short, 0) | |||
-- 用户信息,绑定成功后会包含信息 | |||
, defVar("userInfo", VT_String, "") | |||
-- 奖励金币,只有在ret = 0 时有效,取值0表示没有奖励 | |||
, defVar("rewardCoin", VT_Int, 0) | |||
) | |||
--改变玩家信息request | |||
changePlayerInfoRequest = defClass("changePlayerInfoRequest" | |||
-- uid | |||
, defVar("uid", VT_Int, 0) | |||
-- 微信登陆 openId | |||
, defVar("openId", VT_String, "") | |||
-- 微信登陆 unionId | |||
, defVar("unionId", VT_String, "") | |||
-- 请求类型 | |||
, defVar("loginType", VT_Short, 0) | |||
-- checkcode | |||
, defVar("checkcode", VT_String, "") | |||
-- 微信登陆 weixinInfo | |||
, defVar("weixinInfo", VT_String, "") | |||
) | |||
--改变玩家信息结果 | |||
changePlayerInfoResponse = defClass("changePlayerInfoResponse" | |||
-- 返回类型 | |||
, defVar("ret", VT_Short, 0) | |||
--请求类型 | |||
, defVar("requestType", VT_Short, 0) | |||
--用户信息 | |||
, defVar("userInfo", VT_String, "") | |||
) | |||
------------------------- 玩家相关 ------------------------- | |||
-- 重新组织 userInfo 里面的内容 | |||
function User:updateUserInfo() | |||
local tt = | |||
{ | |||
openid = self.openid, | |||
unionid = self.unionid, | |||
nickname = self.nickname, | |||
sex = self.sex, | |||
headimgurl = self.headimgurl, | |||
areano = self.areano, | |||
gpsInfo = self.gpsInfo, | |||
access_token = self.access_token, | |||
refresh_token = self.refresh_token, | |||
phonenum = self.phonenum, | |||
password = self.password, | |||
deviceInfo = self.strUserDeviceInfo, | |||
--如果是注册手机登录,登录后是5需改为手机登录,这样下次使用缓存登录发给服务器是手机登录,而如果是微信登录就还用原来的登录类型缓存 | |||
loginType = self.loginType == LoginType.LOGIN_TYPE_PHONE_REGISTER and LoginType.LOGIN_TYPE_PHONE or self.loginType, | |||
--新增MD5登录 | |||
isMd5PassWord = self.isMd5PassWord | |||
} | |||
self.userInfo = json.encode(tt); | |||
logD("User:updateUserInfo()", tostring(self.userInfo)) | |||
end | |||
-- 更新GPS信息 | |||
function User:updateGpsInfo(ttGpsInfo) | |||
ttGpsInfo = ttGpsInfo or {gpsStatus = 0, x = 0, y = 0 , addr = ""} | |||
logD("User:updateGpsInfo() ttGpsInfo = ", table.tostring(ttGpsInfo)) | |||
self.gpsInfo = ttGpsInfo | |||
self:updateUserInfo() | |||
end | |||
function User:isGpsInfoNewest(gpsInfo) | |||
logD("User:isGpsInfoSameWithLoc() gpsInfo = ", table.tostring(gpsInfo)) | |||
logD("User:isGpsInfoSameWithLoc() self.gpsInfo = ", table.tostring(self.gpsInfo)) | |||
logD("User:isGpsInfoSameWithLoc() gpsInfo.x = ", string.format("%.6f", gpsInfo.x)) | |||
logD("User:isGpsInfoSameWithLoc() self.gpsInfo.x = ", string.format("%.6f", self.gpsInfo.x)) | |||
logD("User:isGpsInfoSameWithLoc() gpsInfo.y = ", string.format("%.6f", gpsInfo.y)) | |||
logD("User:isGpsInfoSameWithLoc() self.gpsInfo.y = ", string.format("%.6f", self.gpsInfo.y)) | |||
if gpsInfo | |||
and gpsInfo.gpsStatus | |||
and gpsInfo.x | |||
and gpsInfo.y | |||
and gpsInfo.gpsStatus == self.gpsInfo.gpsStatus | |||
and string.format("%.6f", gpsInfo.x) == string.format("%.6f", self.gpsInfo.x) | |||
and string.format("%.6f", gpsInfo.y) == string.format("%.6f", self.gpsInfo.y) then | |||
return true | |||
end | |||
return false | |||
end | |||
--凡是登录前,修改的用户数据都不要本地缓存。 | |||
function User:userLoginEx() | |||
logD("User:userLoginEx()") | |||
if not self.openid or self.openid == "" then | |||
logD("User:userLoginEx() return by openid is nil or empty") | |||
return | |||
end | |||
-- 兼容旧代码,将配置信息往这里拷贝一份 | |||
self.notice = app.serverConfigs.notice; | |||
self.scroll = app.serverConfigs.scroll; | |||
self.gameId = app.serverConfigs.gameId; | |||
self.areano = app.serverConfigs.areano; | |||
self.phpInterface = app.serverConfigs.phpInterface; | |||
self:updateUserInfo(); | |||
-- 请求登录 | |||
local request = LoginRequest:new(); | |||
request.uid = 0; | |||
request.openId = self.openid; | |||
request.unionId = self.unionid; | |||
request.weixinInfo = self.userInfo | |||
request.loginType = self.loginType | |||
request.checkcode = self.checkcode or "" | |||
--如果是验证码登录/密码登录,检查内存是否有密码,有密码则当从后台断网回来前台的时候或者启动游戏自动登录两个情况,自动转化为密码登录。 | |||
if (self.loginType == LoginType.LOGIN_TYPE_PHONE_CHECKCODE or self.loginType == LoginType.LOGIN_TYPE_PHONE) | |||
and self.password and self.password ~= "" and string.len(self.password) > 5 then | |||
logD("yhj User:userLoginEx() AppBase didEnterForground") | |||
self.loginType = LoginType.LOGIN_TYPE_PHONE | |||
self.isMd5PassWord = "1" | |||
self:updateUserInfo() | |||
local tt = json.decode(self.userInfo) | |||
--如果是验证码登录unionid是?,就走不通了。所以先取用户信息里面的手机数据先 | |||
request.openId = tt.phonenum or self.openid; | |||
request.unionId = tt.password or self.unionId; | |||
request.loginType = self.loginType | |||
request.weixinInfo = self.userInfo | |||
elseif self.loginType == LoginType.LOGIN_TYPE_ID and self.password and self.password ~= "" | |||
and string.len(self.password) > 5 then | |||
logD("yhj User:userLoginEx() AppBase didEnterForground") | |||
self.isMd5PassWord = "1" | |||
self:updateUserInfo() | |||
local tt = json.decode(self.userInfo) | |||
--断线重连self.loginInfo.uid肯定是有值,如果是杀掉进程重进,就没有值,这个时候取userinfo里面的值 | |||
request.openId = self.loginInfo.uid ~= 0 and self.loginInfo.uid or tt.openid; | |||
request.unionId = tt.password or self.unionId; | |||
request.loginType = self.loginType | |||
request.weixinInfo = self.userInfo | |||
end | |||
app.waitDialogManager:showWaitNetworkDialog("登录中...") | |||
logD("yhj:User:userLoginEx() request = ", table.tostring(request)) | |||
self:sendResponse{cmd = UserCmd.LoginRequest , sender = request}; | |||
end | |||
-- 登陆结果 | |||
--凡是登录成功后,修改的用户数据都要本地缓存。特别是手机,密码,ID等会影响到登录的 | |||
function User:onLoginResponse(status, response) | |||
logD("User:onLoginResponse()", tostring(status), table.tostring(response)) | |||
local jsonString = response.jsonData | |||
local jsonData = json.decode(jsonString) | |||
if jsonData then | |||
self.openid = jsonData.openid | |||
self.unionid = jsonData.unionid | |||
self.sex = jsonData.sex or self.sex | |||
self.nickname = jsonData.nickname or self.nickname | |||
self.nickname = string.getShortName(self.nickname, 99) | |||
self.headimgurl = jsonData.headimgurl or self.headimgurl | |||
self.phonenum = jsonData.phonenum | |||
self.password = jsonData.password or "" | |||
self.authorize = jsonData.authorize --是否需要二次授权,0则需要 | |||
end | |||
if self.nickname == "" then | |||
logD(" nickname == null ") | |||
self.nickname = "未知昵称" | |||
self.sex = 1 | |||
self.headimgurl = "" | |||
end | |||
self:updateUserInfo(); | |||
-- 关闭延迟的等待 | |||
app.waitDialogManager:closeAllNetWait() | |||
-- 保存玩家的登录信息 | |||
logD("User:onLoginResponse self.loginInfo()1", self.loginInfo) | |||
self.loginInfo = response:updateTo(self.loginInfo) | |||
-- 启动语音插件 | |||
app.plugin:startVoice(); | |||
local ttExtInfo = string.split(self.loginInfo.userInfo, ",") | |||
self.loginInfo.historyCardNum = ttExtInfo[1]; | |||
self.loginInfo.curCardNum = ttExtInfo[2]; | |||
self.loginInfo.curJingbiNum = ttExtInfo[3] or 0 | |||
--金币场等级 | |||
self.serverLevel = response.serverLevel | |||
-- 写入玩家ID到本地 | |||
-- 下次启动游戏时会检测玩家ID是否特殊ID | |||
logD("User:onLoginResponse self.loginInfo()2", self.loginInfo) | |||
saveUserId(self.loginInfo.uid); | |||
local jsonData = response.jsonData | |||
local tt = json.decode(jsonData) or {} | |||
self.loginInfo.token = tt.token or "unkown" | |||
if self.loginType == LoginType.LOGIN_TYPE_WEIXIN or self.loginType == LoginType.LOGIN_TYPE_PHONE | |||
or self.loginType == LoginType.LOGIN_TYPE_PHONE_REGISTER or self.loginType == LoginType.LOGIN_TYPE_PHONE_CHECKCODE | |||
or self.loginType == LoginType.LOGIN_TYPE_ID then | |||
app.php:login() | |||
-- 发送登录成功的事件 | |||
self:dispatchEvent({name = "onLoginSuccessed"}) | |||
self:dispatchEvent({name = "onLoginSuccessedMessage"}) | |||
end | |||
end | |||
-- 使用手机号码登录失败 | |||
function User:onPhoneLoginErrResponse(status, response) | |||
-- 关闭延迟的等待 | |||
app.waitDialogManager:closeAllNetWait() | |||
-- 重置本地账号数据 | |||
self.openid = ""; | |||
self.unionid = ""; | |||
saveUserInfo("local_password",""); | |||
self.loginType = 0 | |||
self.checkcode = "" | |||
self.headimgurl = "" | |||
self.nickname = "" | |||
app.userManager:setLoginRecordCode(0) | |||
local errCode = response.ret | |||
self:dispatchEvent({name = "onPhoneLoginErrResponse", errCode = errCode}); | |||
end | |||
function User:reqestBindApp(bindType, openId) | |||
if not self.loginInfo or not self.loginInfo.uid then | |||
return | |||
end | |||
local request = PhoneBindRequest:new() | |||
request.uid = tonumber(self.loginInfo.uid); | |||
request.account = tostring(openId) | |||
request.bindType = tonumber(bindType) | |||
request.weixinInfo = self.userInfo; | |||
logD("User:reqestBindApp() request = ", table.tostring(request)) | |||
self:sendResponse{cmd = UserCmd.PhoneBindRequest , sender = request}; | |||
end | |||
-- 绑定手机号 | |||
function User:reqestBindPhone(phonenum, checkcode) | |||
if not phonenum or not checkcode then | |||
return | |||
end | |||
local request = PhoneBindRequest:new() | |||
request.uid = self.loginInfo.uid | |||
request.account = phonenum | |||
request.password = "" | |||
request.checkcode = checkcode | |||
request.weixinInfo = app.user.userInfo | |||
request.rewardType = 5 -- 奖励类型:1. 房卡 2.金币 3. 活动房卡 4. RMB 5. 红包券 | |||
logD("User:reqestBindPhone() request = ", table.tostring(request)) | |||
self:sendResponse{cmd = UserCmd.PhoneBindRequest , sender = request}; | |||
end | |||
-- 绑定的结果 | |||
function User:onBindResponse(status, response) | |||
logD("User:onBindResponse() response = ", table.tostring(response)) | |||
--[[ [0] = "绑定成功", | |||
[1] = "验证码错误", | |||
[2] = "已绑定过手机号,无需再次绑定", | |||
[5] = "该手机号已经被其他游戏ID绑定,请更换手机号再次绑定", | |||
[6] = "绑定成功", | |||
[7] = "该微信号已绑定过其他游戏账号", | |||
[8] = "绑定成功", | |||
--]] | |||
if response.ret == BIND_TYPE_RESULT.PHONE then --手机绑定成功 | |||
local stUserInfo = json.decode(response.userInfo) | |||
if stUserInfo then | |||
self.phonenum = stUserInfo.phonenum | |||
self.password = stUserInfo.password | |||
else | |||
logE("User:onBindResponse() stUserInfo is nil") | |||
end | |||
self:updateUserInfo(); | |||
-- 更新本地保存的数据 | |||
local tt = {} | |||
tt.forceCover = true | |||
app.user:dispatchEvent({name = "updateWxUserInfo",response = tt}) | |||
elseif response.ret == BIND_TYPE_RESULT.WEIXIN_TWICE_BIND then --二次授权 | |||
logD("yhj User:onBindResponse() WEIXIN_TWICE_BIND SUCCESS") | |||
local stUserInfo = json.decode(response.userInfo) | |||
if stUserInfo then | |||
self:updateWeiXinInfo(stUserInfo) | |||
self:updateUserInfo(); | |||
-- 更新本地保存的数据 | |||
local tt = {} | |||
tt.forceCover = true | |||
app.user:dispatchEvent({name = "updateWxUserInfo",response = tt}) | |||
end | |||
app:dispatchEvent({name = "showConfirmDialogNotClose"}) | |||
elseif response.ret == BIND_TYPE_RESULT.WEIXIN then --普通微信绑定 | |||
logD("yhj User:onBindResponse() WEIXIN SUCCESS") | |||
local stUserInfo = json.decode(response.userInfo) | |||
if stUserInfo then | |||
self:updateWeiXinInfo(stUserInfo) | |||
self:updateUserInfo(); | |||
-- 更新本地保存的数据 | |||
local tt = {} | |||
tt.forceCover = true | |||
app.user:dispatchEvent({name = "updateWxUserInfo",response = tt}) | |||
end | |||
app:dispatchEvent({name = "showConfirmDialogNotClose"}) | |||
elseif response.ret == BIND_TYPE_RESULT.USER_SET_PASSWORD then --用户设置密码 | |||
logD("yhj User:onBindResponse() USER_SET_PASSWORD SUCCESS") | |||
local stUserInfo = json.decode(response.userInfo) | |||
if stUserInfo then | |||
self.password = stUserInfo.password | |||
else | |||
logE("User:onBindResponse() stUserInfo is nil") | |||
end | |||
self:updateUserInfo(); | |||
-- 更新本地保存的数据 | |||
local tt = {} | |||
tt.forceCover = true | |||
app.user:dispatchEvent({name = "updateWxUserInfo",response = tt}) | |||
else--失败情况暂时只有分发提示事件 | |||
logE("yhj User:onBindResponse() Bind Failed!") | |||
end | |||
self:dispatchEvent({name = "onBindResponse", response = response}); | |||
end | |||
--微信新增字段 | |||
function User:updateWeiXinInfo(weixinInfo) | |||
if weixinInfo then | |||
self.unionid = weixinInfo.unionid or self.unionid | |||
self.openid = weixinInfo.openid or self.openid | |||
self.nickname = weixinInfo.nickname or self.nickname | |||
self.headimgurl = weixinInfo.headimgurl or self.headimgurl | |||
self.sex = weixinInfo.sex or self.sex | |||
self.access_token = weixinInfo.access_token or self.access_token | |||
self.refresh_token = weixinInfo.refresh_token or self.refresh_token | |||
else | |||
logE("weixinInfo is nil") | |||
end | |||
end | |||
-- 改变信息的结果(修改手机号/忘记密码返回) | |||
function User:onChangePlayerInfoResponse(status, response) | |||
logD("yhj:User:onChangePlayerInfoResponse() response = ", table.tostring(response)) | |||
if response.ret == 0 then | |||
local stUserInfo = json.decode(response.userInfo) | |||
local requestType = response.requestType | |||
if stUserInfo then | |||
if requestType == ChangePlayerInfo.REPLCACE_PHONE then | |||
self.phonenum = stUserInfo.phonenum | |||
self:updateUserInfo() | |||
-- 更新本地保存的数据 | |||
local tt = {} | |||
tt.forceCover = true | |||
tt.userInfo = app.user.userInfo | |||
app.user:dispatchEvent({name = "updateWxUserInfo",response = tt}) | |||
elseif requestType == ChangePlayerInfo.PHONE_RESET then | |||
--忘记密码,数据没必要缓存。缓存反而会导致,用户用ID登录输入错误密码,也会用缓存的数据登录 | |||
--[[self.password = stUserInfo.password | |||
self:updateUserInfo() | |||
-- 更新本地保存的数据 | |||
local tt = {} | |||
tt.userInfo = response.userInfo | |||
tt.forceCover = true | |||
app.user:dispatchEvent({name = "updateWxUserInfo",response = tt})--]] | |||
end | |||
else | |||
logE("User:onBindResponse() stUserInfo is nil") | |||
end | |||
end | |||
self:dispatchEvent({name = "onChangePlayerInfo", response = response}); | |||
end | |||
--//////////////////////////////////////////////////////////////////////////// | |||
-- 聊天内容 | |||
ChatMessageRequest = defClass("ChatMessageRequest" | |||
-- //类型 1: 表情 2: 语音 3:聊天 | |||
, defVar("type", VT_Short, 0) | |||
-- //内容,客户端自定义格式 | |||
, defVar("content", VT_String, "") | |||
) | |||
-- 聊天内容 | |||
ChatMessageResponse = defClass("ChatMessageResponse" | |||
-- 用户uid | |||
, defVar("nUserId", VT_Int, 0) | |||
-- //类型 1: 表情 2: 语音 3:聊天 | |||
, defVar("type", VT_Short, 0) | |||
-- //内容,客户端自定义格式 | |||
, defVar("content", VT_String, "") | |||
) | |||
function User:onChatMessageResponse(status, response) | |||
logD("User:onChatMessageResponse(), ", table.tostring(response)) | |||
--[[ | |||
-- 只管发送消息,而不必关注是否有人处理 | |||
if not app.room or not app.room.roomInfo then | |||
print("self.roomInfo no exist,容错处理!") | |||
return | |||
end | |||
--]] | |||
self:dispatchEvent({name = "onChatMessageResponse", response = response}); | |||
end | |||
-- 是否可以发送聊天消息 | |||
function User:canSendChatMessage(chat_type) | |||
if not self.lastChatMessage then | |||
self.lastChatMessage = {} | |||
end | |||
if not self.lastChatMessage[chat_type] then | |||
self.lastChatMessage[chat_type] = 0 | |||
end | |||
local voicePermission = tonumber(loadUserInfo("voicePermission")) or 0 | |||
voicePermission = voicePermission + 1 | |||
logD("User:canSendChatMessage voicePermission out:"..voicePermission) | |||
if voicePermission <= 3 then | |||
logD("User:canSendChatMessage voicePermission:"..tostring(voicePermission)) | |||
saveUserInfo("voicePermission",voicePermission) | |||
return true | |||
end | |||
local ChatDef = require("luaScript.GameChatDefine") | |||
local timeNow = os.time() | |||
local timeLast = self.lastChatMessage[chat_type] or 10 | |||
local timeInterval = ChatDef.TimeInterval[chat_type] or 10 | |||
if timeNow - timeLast >= timeInterval then | |||
return true | |||
else | |||
return false | |||
end | |||
end | |||
function User:sendChatMessage(chat_type, content) | |||
if not self:canSendChatMessage(chat_type) then | |||
return false; | |||
end | |||
self.lastChatMessage[chat_type] = os.time() | |||
local request = ChatMessageRequest:new() | |||
request.type = tonumber(chat_type); | |||
request.content = tostring(content) | |||
log("User:sendChatMessage() request = ", table.tostring(request)); | |||
self:sendResponse{cmd = UserCmd.GAME_COMMAND_CHAT_MESSAGE , sender = request}; | |||
return true; | |||
end | |||
function User:getLastChatTime(chat_type) | |||
return self.lastChatMessage[chat_type] or os.time() | |||
end | |||
function User:onServerKickOutResponse(status, response) | |||
uploadLogs(GAME_ERROR_TYPE.DING_HAO_ERROR) | |||
self.kickOut = true | |||
self:dispatchEvent({name = "onServerKickOutResponse", response = response}) | |||
end | |||
function User:getGameConfig(gameId) | |||
return app.serverConfigs.configs[gameId] | |||
end | |||
function User:ctor(net) | |||
User.super.ctor(self , net, ModuleId); | |||
-- 玩家的个人信息 | |||
self.userInfo = ""; | |||
self.openid = "" | |||
self.unionid = "" | |||
self.nickname = "" | |||
self.sex = 1 | |||
self.headimgurl = "" | |||
self.areano = 0 | |||
self.gpsInfo = {gpsStatus = 0, x = 0, y = 0, addr = ""} | |||
self.access_token = "" | |||
self.refresh_token = "" | |||
self.loginType = 0 | |||
--是否使用md5密码登录 | |||
self.isMd5PassWord = "0" | |||
--是否正在绑定微信 | |||
self.bindWeiXinIng = false | |||
--是否被顶号 | |||
self.kickOut = false | |||
local sysVersion= getSystemVersion(); | |||
local sysName = getSystemName(); | |||
self.userDeviceInfo = | |||
{ | |||
device = getDeviceID(), --设备唯一标识,如有则传,无则无需传输 | |||
machine_type = getLocalizedModel(), --设备型号, "iPhone84"\ "OPPOR11"\ "ASK-AL00x" | |||
os = string.format(sysName..sysVersion) --设备操作系统, "android7.1.2" or "iOS13.3" | |||
} | |||
self.strUserDeviceInfo = json.encode(self.userDeviceInfo) | |||
-- 登录返回的数据 | |||
self.loginInfo = LoginResponse:new() | |||
-- 监听获取配置的消息,成功获取配置后请求登录 | |||
app.serverConfigs:addEventListener("initSuccessed", handler(self, self.userLoginEx)) | |||
-- 请求登陆 | |||
self:defMsgFunc{name = "loginRequest" , cmd = UserCmd.LoginRequest, sender = LoginRequest}; | |||
--请求改变玩家信息(忘记密码,修改手机号) | |||
self:defMsgFunc{name = "playerInfoChange" , cmd = UserCmd.GAME_COMMAND_CHANGE_PLAYER_INFO, sender = changePlayerInfoRequest}; | |||
-- 推送登陆结果 | |||
self:defPushMsg{cmd = UserCmd.LoginResponse , reader = LoginResponse, func = handler(self , self.onLoginResponse)}; | |||
-- 使用手机号码登录失败 | |||
self:defPushMsg{cmd = UserCmd.PhoneLoginErrResponse , reader = PhoneLoginErrResponse, func = handler(self , self.onPhoneLoginErrResponse)}; | |||
-- 请求绑定手机号 | |||
self:defMsgFunc{name = "requestBindPhoneNum" , cmd = UserCmd.PhoneBindRequest, sender = PhoneBindRequest}; | |||
-- 绑定手机号码的结果 | |||
self:defPushMsg{cmd = UserCmd.PhoneBindResponse , reader = PhoneBindResponse, func = handler(self , self.onBindResponse)}; | |||
-- 聊天信息 GAME_COMMAND_CHAT_MESSAGE | |||
self:defPushMsg{cmd = UserCmd.GAME_COMMAND_CHAT_MESSAGE, reader = ChatMessageResponse, func = handler(self , self.onChatMessageResponse)}; | |||
-- 账号在其他地方登陆 | |||
self:defPushMsg{cmd = UserCmd.GAME_COMMAND_CLIENT_KICT_MULTI_LOGIN, reader = IntPacket, func = handler(self , self.onServerKickOutResponse)}; | |||
--改变玩家信息的结果 | |||
self:defPushMsg{cmd = UserCmd.GAME_COMMAND_CHANGE_INFO_RESPONSE, reader = changePlayerInfoResponse, func = handler(self , self.onChangePlayerInfoResponse)}; | |||
end | |||
return User; |
@@ -0,0 +1,322 @@ | |||
local ProtocolZhanJi = class("ProtocolZhanJi") | |||
--[[ | |||
table中的key在经过json转换之后,全部都会变成string,所以在使用的时候都使用string | |||
--]] | |||
local InterfaceKey = | |||
{ | |||
brief = "gamb.brief", -- 获取简要的战绩列表信息 | |||
detail = "gamb.replay", -- 获取某一局的详细战绩 | |||
} | |||
function ProtocolZhanJi:ctor() | |||
-- 添加分发事件的组件 | |||
cc.GameObject.extend(self) | |||
self:addComponent(require("luaScript.cc.components.behavior.EventProtocol"):new()):exportMethods() | |||
self.phpUrl = getGlobalPhpUrl() | |||
-- 保存到本地的文件名,所有子游戏必须重写并且保证不冲突 | |||
self.fileName = ""; | |||
-- 是否茶馆模式 | |||
self.isClubMode = false | |||
-- 每页以及每次拉取最大数量 | |||
self.numPrePage = 20; | |||
-- 茶馆战绩最多保存几天内的数据 | |||
self.numMaxDay = 7; | |||
-- 所有的战绩保存在这里 | |||
self.zhanjiInfoList = {} | |||
end | |||
-- 子游戏的战绩协议应该重写此接口 | |||
function ProtocolZhanJi:init() | |||
end | |||
-- 从本地文件读取以前的战绩信息 | |||
function ProtocolZhanJi:loadFromFile() | |||
local jsonString = loadStringFromFile(self.fileName) | |||
if jsonString then | |||
self.zhanjiInfoList = json.decode(jsonString) or {} | |||
end | |||
end | |||
-- 保存战绩信息到本地文件 | |||
function ProtocolZhanJi:saveToFile() | |||
if self.isClubMode then | |||
-- 茶馆在存储之前要先剔除那些过期的战绩 | |||
-- 首先计算出N天前0点0分0秒对应的时间戳 | |||
local timeBegin = endtime - self.numMaxDay * 24 * 3600 | |||
local dateBegin = os.date("*t", timeBegin) | |||
dateBegin.hour = 0; | |||
dateBegin.min = 0; | |||
dateBegin.sec = 0; | |||
timeBegin = os.time(dateBegin); | |||
-- 逐个比较文件中的数据,剔除过期的内容 | |||
for k,v in pairs(self.zhanjiInfoList) do | |||
local endtime = tonumber(v.endtime) or 0 | |||
if endtime < timeBegin then | |||
self.zhanjiInfoList[k] = nil | |||
end | |||
end | |||
end | |||
local jsonString = json.encode(self.zhanjiInfoList) | |||
saveStringToFile(jsonString, self.fileName) | |||
-- PC端另外再存一份数据以方便查看 | |||
if cc.Application:getInstance():getTargetPlatform() == 0 then | |||
table.saveToLocFile(self.zhanjiInfoList, self.fileName..".lua") | |||
end | |||
end | |||
-- 检查战绩列表,找到需要下载的战绩进行下载 | |||
function ProtocolZhanJi:checkAndDownload(idxList) | |||
local idxListDownload = {} | |||
if idxList then | |||
for k,v in pairs(idxList) do | |||
if not self.zhanjiInfoList[v] then | |||
table.insert(idxListDownload, v) | |||
end | |||
end | |||
end | |||
if table.nums(idxListDownload) >0 then | |||
self:getZhanjiBrief(idxListDownload) | |||
else | |||
self:dispatchEvent({name = "getZhanjiBriefResponse"}) | |||
end | |||
end | |||
-- 获取指定房间的战绩概要 | |||
-- 因为所有子游戏和茶馆的概要信息结构都是一致的。所以可以都使用同一个接口 | |||
-- 如果发现某个游戏的概要信息结构不一样,请通知服务器改动 | |||
function ProtocolZhanJi:getZhanjiBrief(idxListDownload) | |||
local strList | |||
local cnt = 0; | |||
for k,v in pairs(idxListDownload) do | |||
cnt = cnt + 1 | |||
if cnt < self.numPrePage then | |||
if not strList then | |||
strList = tostring(v) | |||
else | |||
strList = strList..","..tostring(v) | |||
end | |||
end | |||
end | |||
local tt = | |||
{ | |||
action = InterfaceKey.brief, -- 接口名 | |||
app = getAppId(), -- appId | |||
uid = app.user.loginInfo.uid, -- userId | |||
idx = strList, -- 索引id,以","分割 | |||
} | |||
logD("ProtocolZhanJi:getZhanjiList()", table.tostring(tt)) | |||
httpPost(self.phpUrl, tt, handler(self, self.getZhanjiBriefResponse)); | |||
end | |||
function ProtocolZhanJi:getZhanjiBriefResponse(status, response) | |||
logD("ProtocolZhanJi:getZhanjiBriefResponse()", status, response) | |||
local ret, ttResult = checkPhpResponse(status, response) | |||
if not ret then | |||
logE("ProtocolZhanJi:getZhanjiBriefResponse()", tostring(ttResult)) | |||
return | |||
end | |||
-- 解析服务器下发的战绩信息 | |||
if ttResult.gamb then | |||
for pid, info in pairs(ttResult.gamb) do | |||
if table.nums(info) > 0 then | |||
local zhanjiInfo = {} | |||
zhanjiInfo.pid = pid; | |||
zhanjiInfo.gameid = info.gameid; -- 游戏ID | |||
zhanjiInfo.gext = info.gext; -- 游戏拓展属性 | |||
zhanjiInfo.roomid = info.roomid; -- 房间号 | |||
zhanjiInfo.fbound = info.fbound; -- 完成的局数 | |||
zhanjiInfo.nbound = info.nbound; -- 需要完成的局数 | |||
zhanjiInfo.endtime = info.endtime; -- 完成时间,unix时间戳 | |||
zhanjiInfo.baseChips = tostring(info.baseChips); -- 底分 | |||
zhanjiInfo.nCards = info.nCards; -- 消耗房卡 | |||
-- 总输赢 | |||
zhanjiInfo.tscore = {} | |||
if info.tscore then | |||
for uid, score in pairs(info.tscore) do | |||
zhanjiInfo.tscore[tostring(uid)] = tonumber(score) | |||
end | |||
end | |||
-- 每个玩家的输赢次数 | |||
zhanjiInfo.tgamb = {} | |||
if info.tgamb then | |||
for uid, wInfo in pairs(info.tgamb) do | |||
zhanjiInfo.tgamb[tostring(uid)] = {win = tonumber(wInfo.w) or 0, lose = tonumber(wInfo.l) or 0}; | |||
end | |||
end | |||
-- 每一局的详细信息 | |||
zhanjiInfo.detail = {} | |||
if info.detail then | |||
for jushu, jushuInfo in pairs(info.detail) do | |||
local jsInfo = {} | |||
-- 每一局下面可能有多轮,所以这里还有一次循环 | |||
for lunshu, lunshuInfo in pairs(jushuInfo) do | |||
local lsInfo = {} | |||
-- 本轮基本信息 | |||
lsInfo.flag = lunshuInfo.flag or 0 -- 0=正常结束 1=吃臭牌 2=吃牌不比 3=无牌赔包子 4=胡臭牌 7=黄庄 8=长时间自动解散 9=解散游戏 , 如果为0、8、9则表示正常结束 | |||
lsInfo.subid = lunshuInfo.subid or "" -- 此次小局结束的日志id | |||
lsInfo.endtime = lunshuInfo.endtime or 0 -- 结束时间 | |||
-- 本轮结算信息 | |||
lsInfo.score = {} | |||
if lunshuInfo.score then | |||
for uid, fenshu in pairs(lunshuInfo.score) do | |||
lsInfo.score[tostring(uid)] = tonumber(fenshu) | |||
end | |||
end | |||
jsInfo[tostring(lunshu)] = lsInfo | |||
end | |||
zhanjiInfo.detail[tostring(jushu)] = jsInfo | |||
end | |||
end | |||
self.zhanjiInfoList[pid] = zhanjiInfo | |||
end | |||
end | |||
end | |||
-- 保存玩家信息 | |||
if ttResult.user then | |||
for uid, info in pairs(ttResult.user) do | |||
local name = tostring(info.n) or tostring(uid) | |||
local head = tostring(info.h) or "" | |||
local sex = tonumber(info.s) or 0 | |||
-- 添加玩家信息到管理器 | |||
if app.playerInfoManager then | |||
app.playerInfoManager:addPlayerInfo(tostring(uid), name, head, sex); | |||
end | |||
end | |||
end | |||
-- 保存到文件 | |||
self:saveToFile() | |||
-- 发送事件 | |||
self:dispatchEvent({name = "getZhanjiBriefResponse" , result = ttResult}) | |||
end | |||
-- 获取指定房间、指定轮数的战绩详情 | |||
-- 对于像黄十八、麻将这种,某一局可能出现吃包子需要打多轮或者详细信息量非常大的情况,必须指定subid | |||
-- 类似扑克这种详情量比较小,可以一次拉取所有局数的数据的,才使用 subid = 0 | |||
function ProtocolZhanJi:getZhanJiDetail(pid, subid, endcallback) | |||
-- 如果连这个战绩的概要信息都没有的话,就不要拉取详细信息了 | |||
local zhanjiInfo = self.zhanjiInfoList[pid] | |||
if not zhanjiInfo then | |||
self:dispatchEvent({name = "getZhanJiDetailResponse"}) | |||
return | |||
end | |||
-- 判断本地是否有这个详情,有就不用更新了 | |||
local needDownload = false; | |||
if zhanjiInfo.detail then | |||
if subid == 0 then | |||
for k,v in pairs(zhanjiInfo.detail) do | |||
if not v.user then | |||
needDownload = true | |||
end | |||
end | |||
else | |||
if not zhanjiInfo.detail[subid] or not zhanjiInfo.detail[subid].user then | |||
needDownload = true | |||
end | |||
end | |||
end | |||
if not needDownload then | |||
self:dispatchEvent({name = "getZhanJiDetailResponse"}) | |||
if endcallback then | |||
endcallback(); | |||
end | |||
return | |||
end | |||
-- 没有这个战绩的详情,还是要从服务器下载 | |||
local tt = | |||
{ | |||
action = InterfaceKey.detail, | |||
app = getAppId(), -- appId | |||
uid = app.user.loginInfo.uid, -- userId | |||
idx = pid, -- 日志ID | |||
subid = subid, -- 小局id 如果需要idx全部战绩,此时subid=0,单个则传subid | |||
} | |||
logD("ProtocolZhanJi:getZhanJiDetail", table.tostring(tt)) | |||
httpPost(self.phpUrl, tt, function(status, response) | |||
self:getZhanJiDetailResponse(status, response, pid, subid, endcallback) | |||
end ) | |||
end | |||
function ProtocolZhanJi:getZhanJiDetailResponse(status, response, pid, subid, endcallback) | |||
logD("ProtocolZhanJi:getZhanJiDetailResponse()", status, response, pid) | |||
local ret, ttResult = checkPhpResponse(status, response) | |||
if not ret then | |||
logE("ProtocolZhanJi:getZhanJiDetailResponse()", tostring(ttResult)) | |||
return | |||
end | |||
local zhanjiInfo = self.zhanjiInfoList[pid] | |||
if zhanjiInfo and zhanjiInfo.detail then | |||
if subid == 0 then | |||
for jushu, lunshuInfo in pairs(ttResult) do | |||
local jsInfo = zhanjiInfo.detail[tostring(jushu)] | |||
if jsInfo then | |||
local lsInfo = jsInfo["1"] | |||
if lsInfo then | |||
for k,v in pairs(lunshuInfo) do | |||
lsInfo[k] = v | |||
end | |||
end | |||
end | |||
end | |||
else | |||
for jushu, jushuInfo in pairs(zhanjiInfo.detail) do | |||
for lunshu, lunshuInfo in pairs(jushuInfo) do | |||
if lunshuInfo.subid == subid then | |||
for k,v in pairs(ttResult) do | |||
lunshuInfo[k] = v | |||
end | |||
end | |||
end | |||
end | |||
end | |||
end | |||
-- 更新本地文件 | |||
self:saveToFile(); | |||
-- 发送事件 | |||
self:dispatchEvent({name = "getZhanJiDetailResponse"}) | |||
-- 执行可能存在的回调 | |||
if endcallback then | |||
endcallback(); | |||
end | |||
end | |||
return ProtocolZhanJi |
@@ -0,0 +1,156 @@ | |||
local ProtocolZhanJiGame = class("ProtocolZhanJiGame", require("luaScript.Protocol.ProtocolZhanJi")) | |||
--[[ | |||
子游戏战绩协议父类 | |||
构造的时候传入子游戏的ID,和战绩保存的文件名 | |||
获取最新战绩的时候调用类型和页数,大多数游戏是不需要传参数的 | |||
--]] | |||
local InterfaceKey = | |||
{ | |||
idx = "gamb.idx", -- 获取战绩ID列表 | |||
} | |||
function ProtocolZhanJiGame:ctor(gameId, fileName) | |||
ProtocolZhanJiGame.super.ctor(self); | |||
self.zhanJiIdxs = {} | |||
self.otherIdxs = {} | |||
self.gameId = gameId | |||
self.fileName = fileName; | |||
self.shareUrl = "http://m.xiaopengol.com/replay.php" --分享战绩链接 | |||
self:loadFromFile() | |||
end | |||
function ProtocolZhanJiGame:init() | |||
ProtocolZhanJiGame.super.init(self) | |||
self:getIdxList() | |||
end | |||
-- 获取最新的战绩列表的key_list | |||
function ProtocolZhanJiGame:getIdxList(mode, page) | |||
local tt = | |||
{ | |||
action = InterfaceKey.idx, -- 接口名 | |||
app = getAppId(), -- appId | |||
uid = app.user.loginInfo.uid, -- userId | |||
gameid = self.gameId, -- gameId | |||
mode = mode or 0, -- 玩法类型,黄十八使用到,默认为0既无特殊玩法 | |||
page = page or 1, -- 页码 | |||
} | |||
logD("ProtocolZhanJiGame:getIdxList()", table.tostring(tt)) | |||
httpPost(self.phpUrl, tt, function(status, response) | |||
self:getIdxlistResponse(status, response, page) | |||
end); | |||
end | |||
-- 获取战绩ID列表的回复 | |||
-- 并和本地数据进行比较,找出本地未下载的部分进行下载 | |||
function ProtocolZhanJiGame:getIdxlistResponse(status, response, page) | |||
logD("ProtocolZhanJiGame:getIdxlistResponse()", status, response) | |||
local ret, ttResult = checkPhpResponse(status, response) | |||
if not ret then | |||
logE("ProtocolZhanJiGame:getIdxlistResponse()", tostring(ttResult)) | |||
return | |||
end | |||
local page = ttResult.page | |||
local tpage = ttResult.tpage | |||
self.tpage = tpage; | |||
-- 只保存属于自己的战绩 | |||
local myUid = app.user.loginInfo.uid | |||
if not self.zhanJiIdxs[myUid] then | |||
self.zhanJiIdxs[myUid] = {} | |||
end | |||
local idxs = {} | |||
for k,pid in pairs(ttResult.idx) do | |||
table.insert(idxs, pid) | |||
end | |||
self.zhanJiIdxs[myUid] = idxs; | |||
if ttResult.url and ttResult.url~="" then | |||
self.shareUrl = ttResult.url | |||
end | |||
self:checkAndDownload(ttResult.idx); | |||
end | |||
-- 获取属于自己的战绩 | |||
function ProtocolZhanJiGame:getZhanJiList() | |||
-- 首先找到对应的 idx_list | |||
local myUid = app.user.loginInfo.uid | |||
if not self.zhanJiIdxs[myUid] then | |||
return {} | |||
end | |||
local function sortFuncEx(a,b) | |||
local numA = toNumber(a.endtime) | |||
local numB = toNumber(b.endtime) | |||
if numA ~= nil and numB ~= nil then | |||
return numA > numB | |||
else | |||
return a > b | |||
end | |||
end | |||
local zhanjiList = {} | |||
local idx_list = self.zhanJiIdxs[myUid] | |||
for _,pid in pairs(idx_list) do | |||
if self.zhanjiInfoList[pid] then | |||
table.insert(zhanjiList,self.zhanjiInfoList[pid]) | |||
end | |||
end | |||
table.sort(zhanjiList,sortFuncEx) | |||
return zhanjiList; | |||
end | |||
function ProtocolZhanJiGame:requestOtherZhanji(idx) | |||
local idxs = {} | |||
if idx then | |||
table.insert(idxs,idx) | |||
-- self.lastSearchIdx = idx | |||
table.insert(self.otherIdxs,idx) | |||
end | |||
if #self.otherIdxs==0 then | |||
return | |||
end | |||
self:checkAndDownload(idxs) | |||
end | |||
function ProtocolZhanJiGame:getZhanJiListOther() | |||
local zhanjiList = {} | |||
local function sortFuncEx(a,b) | |||
local numA = toNumber(a.endtime) | |||
local numB = toNumber(b.endtime) | |||
if numA ~= nil and numB ~= nil then | |||
return numA > numB | |||
else | |||
return a > b | |||
end | |||
end | |||
local idx_list = self.zhanJiIdxs[myUid] | |||
for _,pid in pairs(self.otherIdxs) do | |||
if self.zhanjiInfoList[pid] then | |||
table.insert(zhanjiList,self.zhanjiInfoList[pid]) | |||
end | |||
end | |||
table.sort(zhanjiList,sortFuncEx) | |||
return zhanjiList; | |||
end | |||
return ProtocolZhanJiGame; |
@@ -0,0 +1,246 @@ | |||
-- 用来实现自动倒计时,并可以做数据绑定,具体用法参考VT_RemainTime.lua | |||
local RemainTime = class("RemainTime"); | |||
function RemainTime:ctor() | |||
-- 当前剩余秒数,每秒更新一次,可绑定 | |||
self.Value = 0; | |||
-- 总剩余时间(单位秒,外部设置),可绑定 | |||
self.RemainTime = 0; | |||
-- 上次更新的本地时间 | |||
self.LastTime = 0 | |||
-- 总共流失了多少时间 | |||
self.TotalElapse = 0 | |||
-- 开始倒计时的时间(os.time()获取) | |||
self.StartTime = 0; | |||
-- 计时到0后,回调OnTimeOver(self) | |||
self.OnTimeOver = nil; | |||
-- 数据绑定列表,key是变量名(Value或RemainTime),value是Binder表 | |||
self.BindsByName = {} | |||
-- 根据索引排序的绑定列表,key是BindIndex,value是Binder表 | |||
self.BindsByIndex = {} | |||
-- 绑定索引 | |||
self.BindIndex = 0; | |||
-- 每隔多久触发一次 | |||
self.Interval = 1; | |||
-- 定时器速度 | |||
self.Speed = 1; | |||
-- 暂停状态 | |||
self.Pause = false; | |||
end | |||
function RemainTime:setInterval(interval) | |||
if self.Interval ~= interval then | |||
self.Interval = interval; | |||
if self.TimerID then | |||
self:stopTimer(); | |||
self:startTimer(); | |||
end | |||
end | |||
end | |||
-- 设置加速速度 | |||
function RemainTime:setSpeed(speed) | |||
self.Speed = speed | |||
end | |||
-- 设置剩余秒数多少 | |||
function RemainTime:setRemainTime(seconds) | |||
--print("设置倒计时" , seconds); | |||
if type(seconds) == "table" then | |||
seconds = seconds:getRemainTime(); | |||
end | |||
self.RemainTime = seconds; | |||
self.Value = seconds; | |||
self.StartTime = os.time() | |||
self.LastTime = self.StartTime | |||
self.TotalElapse = 0 | |||
self:triggerBinder("RemainTime"); | |||
self:triggerBinder("Value"); | |||
-- 开始计时 | |||
if self.Value > 0 and next(self.BindsByIndex) ~= nil and self.Pause == false then | |||
self:startTimer(); | |||
end | |||
end | |||
function RemainTime:getRemainTime() | |||
return self.RemainTime; | |||
end | |||
function RemainTime:updateTo(target) | |||
target.Value = self.Value; | |||
target.RemainTime = self.RemainTime; | |||
target.StartTime = self.StartTime; | |||
target.LastTime = self.LastTime | |||
target.TotalElapse = self.TotalElapse | |||
target.Speed = self.Speed | |||
if target.startTimer and target.Value > 0 and next(target.BindsByIndex) ~= nil and target.Pause == false then | |||
target:startTimer() | |||
end | |||
return target; | |||
end; | |||
-- 获取一个绑定实例 | |||
function RemainTime:getBinder(valueName) | |||
local bindTable = self.BindsByName[valueName]; | |||
-- 根据名字创建绑定表,一个名字可以绑定多次 | |||
if bindTable == nil then | |||
bindTable = {}; | |||
self.BindsByName[valueName] = bindTable; | |||
end | |||
self.BindIndex = self.BindIndex + 1 | |||
-- 创建单个绑定实例 | |||
local binder = | |||
{ | |||
TargetNode = nil; | |||
ValueName = valueName; | |||
BindIndex = self.BindIndex; | |||
OnPropChanged = nil | |||
}; | |||
self.BindsByIndex[binder.BindIndex] = binder; | |||
bindTable[binder.BindIndex] = binder; | |||
return binder; | |||
end | |||
-- 每秒回调一次 | |||
function RemainTime:onTimer() | |||
local now = os.time() | |||
local elapse = (now - self.LastTime) * self.Speed; | |||
self.TotalElapse = self.TotalElapse + elapse | |||
self.LastTime = now | |||
-- 计算剩余时间 | |||
self.Value = self.RemainTime - self.TotalElapse; | |||
if self.Value <= 0 then | |||
self.Value = 0; | |||
end | |||
--print("计算剩余时间:" , self.Value , self.RemainTime , seconds , now , self.StartTime); | |||
-- 触发数据修改通知 | |||
self:triggerBinder("Value"); | |||
-- 倒计时结束 | |||
if self.Value <= 0 then | |||
--print("倒计时结束" , self.Value); | |||
self:stopTimer(); | |||
if self.OnTimeOver then | |||
self.OnTimeOver(self); | |||
end; | |||
end; | |||
end | |||
-- 触发数据修改通知 | |||
function RemainTime:triggerBinder(valueName) | |||
local value = self[valueName]; | |||
--print("值改变:" , valueName , value); | |||
local binders = self.BindsByName[valueName]; | |||
if binders then | |||
for i , v in pairs(binders) do | |||
v.OnPropChanged(valueName , value); | |||
end | |||
end | |||
end | |||
-- 开始计时器 | |||
function RemainTime:startTimer() | |||
if self.Pause then | |||
return | |||
end | |||
if self.TimerID == nil then | |||
self.TimerID = cc.Director:getInstance():getScheduler():scheduleScriptFunc(function()self:onTimer()end, self.Interval, false); | |||
end | |||
end | |||
-- 停止计时器 | |||
function RemainTime:stopTimer() | |||
if self.TimerID then | |||
cc.Director:getInstance():getScheduler():unscheduleScriptEntry(self.TimerID); | |||
self.TimerID = nil; | |||
end | |||
end | |||
-- 暂停计时器(计时器就不走了) | |||
function RemainTime:pause() | |||
if self.Pause then | |||
return | |||
end | |||
self:stopTimer() | |||
-- 执行一次时间 | |||
self:onTimer() | |||
self.Pause = true | |||
end | |||
-- 恢复计时器 | |||
function RemainTime:resume() | |||
if not self.Pause then | |||
return | |||
end | |||
self.Pause = false | |||
-- 如果时间完了就不能开始了 | |||
if self.Value <= 0 then | |||
print("计时器时间已经流失完了,恢复失败") | |||
return | |||
end | |||
-- 重新设置下时间 | |||
self:setRemainTime(self.Value) | |||
end | |||
-- 实现自动绑定数据的函数 | |||
-- @valueName 需要绑定哪个变量名 | |||
-- @propertyNameOrFunc , 当添加事件发生时的回调或设置什么属性,回调格式是func(key , value); | |||
-- @return 返回绑定索引 | |||
function RemainTime:bind(valueName , propertyNameOrFunc , targetNode) | |||
local onPropChange; | |||
local typeP = type(propertyNameOrFunc); | |||
if typeP == "function" then | |||
onPropChange = function(key , value) | |||
propertyNameOrFunc(self , value); | |||
end | |||
elseif typeP == "string" then | |||
local function onChange(key , value) | |||
self[propertyNameOrFunc](self , value); | |||
end | |||
onPropChange = onChange | |||
else | |||
error("绑定数据" .. tostring(valueName) .. "时第三个参数错误,必须是属性名或函数" .. tostring(propertyNameOrFunc)) | |||
return; | |||
end | |||
local binder = self:getBinder(valueName); | |||
binder.TargetNode = targetNode; | |||
binder.OnPropChanged = onPropChange; | |||
-- 开始计时 | |||
if self.Value > 0 then | |||
self:startTimer(); | |||
end | |||
self:triggerBinder(valueName); | |||
return binder.BindIndex; | |||
end | |||
-- 解除绑定 | |||
function RemainTime:unbind(bindIndex) | |||
local binder = self.BindsByIndex[bindIndex]; | |||
if binder == nil then | |||
print("找不到绑定索引" .. tostring(bindIndex)); | |||
return; | |||
end | |||
self.BindsByName[binder.ValueName][bindIndex] = nil; | |||
self.BindsByIndex[bindIndex] = nil; | |||
-- 没人绑定了,就停止计时器 | |||
if next(self.BindsByIndex) == nil then | |||
self:stopTimer(); | |||
end | |||
end | |||
return RemainTime; |
@@ -0,0 +1,137 @@ | |||
-- 实现加载配置进度条 | |||
local StartupProgressView = {}; | |||
StartupProgressView.__index = StartupProgressView; | |||
-- 创建新对象 | |||
function StartupProgressView:new(...) | |||
local instance = {}; | |||
setmetatable(instance , StartupProgressView); | |||
instance:ctor(...); | |||
return instance; | |||
end | |||
function StartupProgressView:ctor() | |||
self:onEnter(); | |||
end | |||
-- 创建更新界面 | |||
local function createUpdateUI() | |||
local ui = loadUI("res/ui/ui_denglu/ui_loading.ui") | |||
return ui | |||
end | |||
function StartupProgressView:initMainScene() | |||
-- initialize director | |||
local director = cc.Director:getInstance(); | |||
local resolutionSize = director:getOpenGLView():getDesignResolutionSize() | |||
self.mainScene = cc.Scene:create("mainScene"); | |||
self.mainScene:setContentSize(resolutionSize); | |||
self.mainScene:setAnchorPoint({x=0,y=0}); | |||
if director:getRunningScene() then | |||
director:replaceScene(self.mainScene); | |||
else | |||
director:runWithScene(self.mainScene); | |||
end | |||
end | |||
function StartupProgressView:onEnter() | |||
self:initMainScene(); | |||
self.ui = createUpdateUI(); | |||
self.mainScene:addChild(self.ui); | |||
-- 找到所有已经安装的游戏 | |||
self.insGameList = {} | |||
for _,gameId in pairs(GAME_IDS) do | |||
local clientUpdateFile = "update_"..tostring(gameId)..".json" | |||
if isWritableFileExist(clientUpdateFile) then | |||
table.insert(self.insGameList, gameId); | |||
end | |||
end | |||
self:initFramework() | |||
self.Count = table.nums(self.insGameList); | |||
self.Current = 0; | |||
self:checkConfig(); | |||
end | |||
--添加框架到文件系统 | |||
function StartupProgressView:initFramework() | |||
local frameworks={ | |||
1001,--麻将 | |||
1002,--字牌 | |||
1003,--扑克 | |||
} | |||
for _,gameId in pairs(frameworks) do | |||
local clientUpdateFile = "update_"..tostring(gameId)..".json" | |||
if isWritableFileExist(clientUpdateFile) then | |||
table.insert(self.insGameList, gameId); | |||
end | |||
end | |||
end | |||
-- 一次只加载一个配置 | |||
function StartupProgressView:checkConfig() | |||
self.ui:runInNextFrame(function() | |||
if self.Current < self.Count then | |||
-- 每帧加载一个子游戏的文件列表 | |||
self.Current = self.Current + 1 | |||
self:loadSubGameFileList(self.insGameList[self.Current]); | |||
-- 循环 | |||
self:checkConfig() | |||
else | |||
self:onExit() | |||
end | |||
end) | |||
end | |||
function StartupProgressView:loadSubGameFileList(gameId) | |||
if not gameId then | |||
return | |||
end | |||
local clientUpdateFile = "update_"..tostring(gameId)..".json" | |||
if not isWritableFileExist(clientUpdateFile) then | |||
return | |||
end | |||
-- 加载本地旧的文件列表 | |||
local function onStartElementOld(name , atts) | |||
if name == "file" then | |||
local info = | |||
{ | |||
isRomFile = false; | |||
origin = atts.origin; | |||
name = atts.name; | |||
md5 = atts.md5; | |||
size = tonumber(atts.size), | |||
realFilePath = getWritableFullName(atts.md5); | |||
}; | |||
cc.FilePackage:getInstance():addFile(info); | |||
end | |||
end | |||
local fileData = getWritableFileData(clientUpdateFile); | |||
local fileData = cc.FilePackage:decrypt(fileData) | |||
local ret , result = tiny.eval(fileData , onStartElementOld) | |||
if ret == nil then | |||
log("Error, StartupProgressView:loadSubGameFileList() ", gameId) | |||
logE(result); | |||
end | |||
end | |||
-- 进度加载完毕,退出进度条,真正进入游戏 | |||
function StartupProgressView:onExit() | |||
self.ui:removeFromParent(); | |||
require("luaScript.ViewTouchEventHelper") | |||
require("luaScript.gameApp"):new():run() | |||
end | |||
return StartupProgressView; |
@@ -0,0 +1,120 @@ | |||
-- 文件下载器 | |||
local FileDownloader = class("FileDownloader") | |||
-- urls : 下载地址 | |||
-- fileName :保存在本地的文件名 | |||
-- onFinishCallback : 完成后的回调 | |||
function FileDownloader:ctor(urls, atts, onFinishCallback) | |||
self.urls = urls | |||
self.atts = atts | |||
self.onFinishCallback = onFinishCallback; | |||
end | |||
-- 开启下载 | |||
function FileDownloader:start() | |||
local priority = 0 | |||
local startPos = self.atts.offset or 0 | |||
local dataSize = self.atts.compressedSize or 0 | |||
local timebegin; | |||
local index = 0; | |||
local function downloadFileFromUrl() | |||
local function onUpdateFirst(status , data) | |||
if status == "successed" then | |||
-- 打印下载文件的耗时 | |||
local timeEnd = os.time() | |||
logI(string.format("FileDownloader() cost time = %4s , size = %8s , file = %s", timeEnd - timebegin, dataSize, self.atts.name)) | |||
-- 下载成功后将数据保存为本地文件 | |||
self:onDownloadSuccessed(data); | |||
else | |||
-- 下载失败后再次请求下载 | |||
downloadFileFromUrl() | |||
end | |||
end | |||
index = index + 1 | |||
if not self.urls[index] then | |||
logE("FileDownloader:start() url is nil") | |||
return | |||
end | |||
timebegin = os.time() | |||
self.task = cc.CURLManager:getInstance():createTask(self.urls[index], onUpdateFirst , priority , startPos , dataSize); | |||
end | |||
downloadFileFromUrl(); | |||
end | |||
-- 取消下载 | |||
function FileDownloader:cancel() | |||
if self.task then | |||
cc.CURLManager:getInstance():cancelTask(self.task); | |||
self.task = nil | |||
end | |||
end | |||
function FileDownloader:onDownloadSuccessed(data) | |||
local targetFilename = cc.FileUtils:getInstance():getWritablePath() .. self.atts.md5 | |||
local uncompressData = lzma.uncompress(data); | |||
-- 解压成功 | |||
if uncompressData then | |||
local targetFile = io.open(targetFilename , "wb"); | |||
if targetFile == nil then | |||
return; | |||
end | |||
targetFile:write(uncompressData); | |||
targetFile:close(); | |||
else | |||
logE("文件解压失败:" , self.atts.name , "压缩文件大小:" , #data , "/" , self.atts.compressedSize) ; | |||
return; | |||
end | |||
-- win32平台下面文件系统是不会起作用的 | |||
if not isWin32Platform() then | |||
-- 加到文件系统中 | |||
self:addFile(); | |||
--[[ | |||
-- 检查MD5 | |||
local md5Result = cc.FilePackage:calcFileMd5(targetFilename); | |||
if md5Result ~= self.atts.md5 then | |||
logE("文件下载完毕,但是文件的md5跟服务器上面记录的md5不一致,删除本地文件:", targetFilename) | |||
os.remove(targetFilename); | |||
return; | |||
end | |||
--]] | |||
end | |||
self:onFinish() | |||
end | |||
-- 添加文件信息到打包文件系统中 | |||
function FileDownloader:addFile() | |||
local info = | |||
{ | |||
isRomFile = false; | |||
origin = self.atts.origin; | |||
name = self.atts.name; | |||
md5 = self.atts.md5; | |||
size = tonumber(self.atts.size), | |||
realFilePath = getWritableFullName(self.atts.md5); | |||
}; | |||
print("加到文件系统" , info.realFilePath , self.atts.md5 , self.atts.name); | |||
cc.FilePackage:getInstance():addFile(info); | |||
end | |||
-- 下载完成 | |||
function FileDownloader:onFinish() | |||
if self.onFinishCallback then | |||
self.onFinishCallback() | |||
end | |||
end | |||
return FileDownloader |
@@ -0,0 +1,159 @@ | |||
local SubGameConfigManager = class("SubGameConfigManager") | |||
function SubGameConfigManager:ctor() | |||
self.subGameConfigs = {} | |||
self.subGameConfigPath = "dataconfig" | |||
self.subGameConfigFileName = "SubGameConfig_%03d.json" | |||
self.isInited = false | |||
end | |||
-- 初始化所有子游戏的配置信息 | |||
function SubGameConfigManager:init() | |||
logD("SubGameConfigManager:init()") | |||
self.subGameConfigs = {} | |||
-- 先使用的本地的数据初始化 | |||
local subGameIds = app.serverConfigs:getSubGameIds() | |||
for _, gameId in pairs(subGameIds) do | |||
self:_initSubGameConfig(gameId) | |||
end | |||
-- 然后获取服务器最新的数据 | |||
self:_requestLastestConfigs() | |||
end | |||
-- 获取单个子游戏的配置信息 | |||
-- 如果配置未找到,则返回nil | |||
function SubGameConfigManager:getSubGameConfig(gameId) | |||
logD("SubGameConfigManager:getSubGameConfig(), gameId = " .. tostring(gameId)) | |||
gameId = tonumber(gameId) | |||
if not gameId or gameId <= 0 or gameId >= 1000 then | |||
return nil | |||
end | |||
return self.subGameConfigs[gameId] | |||
end | |||
-- 初始化单个子游戏的配置信息 | |||
function SubGameConfigManager:_initSubGameConfig(gameId) | |||
logD("SubGameConfigManager:_initSubGameConfig(), gameId = " .. tostring(gameId)) | |||
gameId = tonumber(gameId) | |||
if not gameId or gameId <= 0 or gameId >= 1000 then | |||
return | |||
end | |||
local writablePath = cc.FileUtils:getInstance():getWritablePath(); | |||
local jsonFileName = string.format(self.subGameConfigFileName, gameId) | |||
local jsonFilePath = self.subGameConfigPath .. "/" .. jsonFileName | |||
if isFileExist(jsonFilePath) then | |||
-- 读取文本数据 | |||
local fileString = getFileData(jsonFilePath) | |||
if fileString == nil or fileString == "" then | |||
logD("SubGameConfigManager:_initSubGameConfig(), fileString = " .. tostring(fileString)) | |||
return | |||
end | |||
-- 非WIN32要解密 | |||
if not isWin32Platform() then | |||
fileString = cc.FilePackage:decrypt(fileString) | |||
end | |||
-- 转json对象 | |||
local jsonData = json.decode(fileString) | |||
if not jsonData or type(jsonData) ~= "table" then | |||
logD("SubGameConfigManager:_initSubGameConfig(), jsonData = " .. table.tostring(jsonData)) | |||
return | |||
end | |||
self.subGameConfigs[gameId] = jsonData | |||
else | |||
logD("SubGameConfigManager:_initSubGameConfig(), file not exist, gameId = " .. gameId) | |||
end | |||
end | |||
-- 获取所有子游戏的最新配置信息 | |||
function SubGameConfigManager:_requestLastestConfigs() | |||
if self.isInited then | |||
return | |||
end | |||
logD("SubGameConfigManager:_requestLastestConfigs()") | |||
local subGameIds = app.serverConfigs:getSubGameIds() | |||
local versionString = "" | |||
for _, gameId in pairs(subGameIds) do | |||
local subGameVersion = app.subGameManager:getSubGameVersionNum(gameId) | |||
if versionString == "" then | |||
versionString = tostring(gameId) .. "," .. tostring(subGameVersion) | |||
else | |||
versionString = versionString .. "|" .. tostring(gameId) .. "," .. tostring(subGameVersion) | |||
end | |||
end | |||
local tt = | |||
{ | |||
action = "system.gamestruct", | |||
apkver = getAppVersionNum(), | |||
app = getAppId(), | |||
uid = loadUserId(), | |||
gameid = versionString, | |||
} | |||
logD("SubGameConfigManager:_requestLastestConfigs() tt = ", table.tostring(tt)) | |||
httpPost(getGlobalPhpUrl(), tt, handler(self, self.onGetLastestConfigsResponse)) | |||
end | |||
function SubGameConfigManager:onGetLastestConfigsResponse(status, response) | |||
logD(string.format("SubGameConfigManager:onGetLastestConfigsResponse(), status = %s response = %s", tostring(status), tostring(response))) | |||
if status ~= "successed" or not response then | |||
return | |||
end | |||
local stResponse = json.decode(response) | |||
if not stResponse or type(stResponse) ~= "table" or not stResponse.result or type(stResponse.result) ~= "table" then | |||
return | |||
end | |||
-- 标记为初始化完成 | |||
self.isInited = true | |||
for gameId,gameConfig in pairs(stResponse.result) do | |||
if gameConfig and type(gameConfig) == "table" and table.nums(gameConfig) > 0 then | |||
self:_saveSubGameConfig(gameId, gameConfig) | |||
end | |||
end | |||
-- 重新初始化,将最新的数据读入内存 | |||
self:init() | |||
end | |||
-- 保存单个子游戏的配置信息到缓存文件 | |||
function SubGameConfigManager:_saveSubGameConfig(gameId, jsonData) | |||
logD("SubGameConfigManager:_saveSubGameConfig(), gameId = " .. tostring(gameId)) | |||
logD("SubGameConfigManager:_saveSubGameConfig(), jsonData = " .. tostring(jsonData)) | |||
gameId = tonumber(gameId) | |||
if not gameId or gameId <= 0 or gameId >= 1000 then | |||
return | |||
end | |||
if jsonData == nil or jsonData == "" then | |||
return | |||
end | |||
local fileString = json.encode(jsonData) | |||
-- 非WIN32要加密保存 | |||
if not isWin32Platform() then | |||
fileString = cc.FilePackage:encrypt(fileString) | |||
end | |||
local writablePath = cc.FileUtils:getInstance():getWritablePath(); | |||
local subGameConfigPath = writablePath .. self.subGameConfigPath | |||
if not cc.FileUtils:getInstance():isDirectoryExist(subGameConfigPath) then | |||
cc.FileUtils:getInstance():createDirectory(subGameConfigPath) | |||
end | |||
local jsonFileName = string.format(self.subGameConfigFileName, gameId) | |||
local jsonFilePath = self.subGameConfigPath .. "/" .. jsonFileName | |||
saveStringToFile(fileString, jsonFilePath) | |||
end | |||
return SubGameConfigManager |
@@ -0,0 +1,50 @@ | |||
-- 子游戏 | |||
-- 包括检测、下载 | |||
local SubGameLoadView = class("SubGameLoadView", cc.UIView) | |||
function SubGameLoadView:ctor(gameId, endCallback) | |||
SubGameLoadView.super.ctor(self) | |||
self.gameId = gameId | |||
self.endCallback = endCallback; | |||
self.ui = loadUI("res/ui/ui_dating/ui_xiazai_jindu.ui") | |||
self:addChild(self.ui) | |||
end | |||
function SubGameLoadView:onEnter() | |||
SubGameLoadView.super.onEnter(self) | |||
self.percentText = "" | |||
--游戏是否已下载 | |||
local gameIsInstaller = app.subGameManager:isInstaller(self.gameId) | |||
if gameIsInstaller then | |||
self.percentText = "更新中..." | |||
else | |||
self.percentText = "下载中..." | |||
end | |||
self.ui.Items.LoadingBar:setPercent(0) | |||
if app.subGameManager then | |||
app.subGameManager:updateSubGame(self.gameId, handler(self, self.updatePercent), handler(self, self.updateFinish)) | |||
end | |||
end | |||
function SubGameLoadView:updatePercent(num) | |||
if num < 0 then num = 0 end | |||
if num > 100 then num = 100 end | |||
self.ui.Items.LoadingBar:setPercent(num or 0) | |||
self.ui.Items.Text_Percent:setText(string.format("%s%d%%", self.percentText, num)) | |||
end | |||
function SubGameLoadView:updateFinish() | |||
if self.endCallback then | |||
self.endCallback() | |||
end | |||
self:removeFromParent() | |||
end | |||
return SubGameLoadView |
@@ -0,0 +1,476 @@ | |||
--[[ | |||
管理所有子游戏的版本信息,更新状态,及更新子游戏 | |||
负责下载所有子游戏的游戏图标,并将图标时间记录下来 | |||
从SubGameVersionManager获取子游戏最新的版本信息 | |||
从本地文件中获取子游戏当前的版本信息 | |||
判断子游戏是否需要更新 | |||
提供子游戏更新的接口 | |||
子游戏列表及当前版本号存本地文件, | |||
subGameList = | |||
{ | |||
[gameId] = "1022", | |||
[gameId] = "1022", | |||
} | |||
--]] | |||
local SubGameVersionManager = class("SubGameVersionManager") | |||
function SubGameVersionManager:ctor() | |||
cc.GameObject.extend(self) | |||
self:addComponent(require("luaScript.cc.components.behavior.EventProtocol"):new()):exportMethods() | |||
-- 是否测试下载 | |||
self.isTestUpdate = false | |||
-- 子游戏列表 | |||
self.subGameList = {} | |||
-- 本地记录的文件信息 | |||
self.GameVersionsKey = "GameVersions"; | |||
self.GameVersions = {} | |||
-- self.GameVersions[3] = 10000; | |||
-- self.GameVersions[6] = 1000; | |||
--基础包 | |||
--self.GameVersions[1001] = -1; | |||
--self.GameVersions[1002] = -1; | |||
--self.GameVersions[1003] = -1; | |||
-- 从本地读取已经安装的子游戏列表 | |||
-- 以及每个子游戏的当前版本号 | |||
self:loadVersionsFromFile() | |||
--处理一下基础包的版本号 | |||
self.GameVersions[1001] = self.GameVersions[1001]==1000 and -1 or self.GameVersions[1001] | |||
self.GameVersions[1002] = self.GameVersions[1002]==1000 and -1 or self.GameVersions[1002] | |||
self.GameVersions[1003] = self.GameVersions[1003]==1000 and -1 or self.GameVersions[1003] | |||
-- self.GameVersions[3] = self.GameVersions[3]==10000 and -1 or self.GameVersions[3] | |||
-- 子游戏下载器 | |||
self.updaterList = {} | |||
--排序 | |||
self.info = {}; | |||
-- self:loadFromFile(); | |||
end | |||
-- 获取子游戏的版本 | |||
-- 如果指定的游戏没有安装,则返回-1 | |||
function SubGameVersionManager:getSubGameVersionNum(gameId) | |||
gameId = tonumber(gameId) | |||
if self.GameVersions[gameId] then | |||
return self.GameVersions[gameId] | |||
else | |||
return -1 | |||
end | |||
end | |||
-- 从本地读取游戏版本信息 | |||
function SubGameVersionManager:loadVersionsFromFile() | |||
local locString = loadUserInfo(self.GameVersionsKey) | |||
if not locString or locString == "" then | |||
return | |||
end | |||
logD("SubGameVersionManager:loadVersionsFromFile() locString = ", locString) | |||
local locData = json.decode(locString) | |||
if locData then | |||
for k,v in pairs(locData) do | |||
self.GameVersions[tonumber(k)] = tonumber(v) | |||
end | |||
else | |||
logD("SubGameVersionManager:loadVersionsFromFile() locString:"..locString) | |||
end | |||
end | |||
-- 将游戏版本信息写入到本地 | |||
function SubGameVersionManager:saveVersionsToFile() | |||
local locString = json.encode(self.GameVersions) | |||
logD("SubGameVersionManager:saveVersionsToFile() locString = ", locString) | |||
saveUserInfo(self.GameVersionsKey, locString) | |||
end | |||
-- 保存子游戏的资源版本号 | |||
function SubGameVersionManager:saveSubGameVersion(gameId, newVersion) | |||
if not self.GameVersions then | |||
self.GameVersions = {} | |||
end | |||
self.GameVersions[tonumber(gameId)] = newVersion | |||
self:saveVersionsToFile() | |||
end | |||
-- 子游戏是否已安装 | |||
function SubGameVersionManager:isInstaller(gameId) | |||
gameId = tonumber(gameId) | |||
-- WIN32且未开启测试,则默认已安装 | |||
if isWin32Platform() and self.isTestUpdate == false then | |||
return true | |||
end | |||
if (gameId and self.GameVersions and self.GameVersions[gameId]) then | |||
return true | |||
else | |||
return false | |||
end | |||
end | |||
-- 子游戏是否需要更新 | |||
function SubGameVersionManager:isNeedUpdate(gameId) | |||
logD("SubGameVersionManager:isNeedUpdate()", gameId) | |||
-- WIN32且未开启测试,则默认不需要更新 | |||
if isWin32Platform() and self.isTestUpdate == false then | |||
return false | |||
end | |||
-- 检查该游戏的基础包 | |||
local subGameConfig = getSubGameConfig(gameId) | |||
if subGameConfig and subGameConfig.fremworkId then | |||
if self:isNeedUpdate(subGameConfig.fremworkId) then | |||
return true | |||
end | |||
end | |||
local verLocal = self:getSubGameVersionNum(gameId) | |||
local verServer = app.serverConfigs:getSubGameVersionNum(gameId) | |||
logD(string.format("SubGameVersionManager:isNeedUpdate() gameId = %s, verLocal = %s, verServer = %s", gameId, verLocal, verServer)) | |||
-- 如果本地没有安装,肯定是需要更新的 | |||
if tonumber(verLocal) == -1 then | |||
logD(string.format("SubGameVersionManager:isNeedUpdate() gameId = %s, verLocal = %s", gameId, verLocal)) | |||
return true | |||
end | |||
-- 无需更新的情况 | |||
if tonumber(verServer) == 0 or tonumber(verLocal) == tonumber(verServer) then | |||
logD("SubGameVersionManager:isNeedUpdate() 无需更新") | |||
return false | |||
end | |||
-- 正常更新 | |||
if tonumber(verLocal) < tonumber(verServer) then | |||
logD("SubGameVersionManager:isNeedUpdate() 正常更新") | |||
return true | |||
end | |||
-- 版本回退 | |||
if tonumber(verLocal) > tonumber(verServer) then | |||
logD("SubGameVersionManager:isNeedUpdate() 版本回退") | |||
local writablePath = cc.FileUtils:getInstance():getWritablePath() | |||
local rootName = nil | |||
local subGameConfig = getSubGameConfig(gameId) | |||
if subGameConfig then | |||
rootName = subGameConfig.rootName | |||
elseif FRAMEWORK_DIR[gameId] then | |||
rootName = FRAMEWORK_DIR[gameId] | |||
end | |||
logD("SubGameVersionManager:isNeedUpdate() rootName = ", tostring(rootName)) | |||
if rootName then | |||
local subGameResPath = writablePath .. RomSetting.Platform .. "/" .. rootName .. "/" | |||
logD("SubGameVersionManager:isNeedUpdate() subGameResPath = ", subGameResPath) | |||
cc.FileUtils:getInstance():removeDirectory(subGameResPath) | |||
cc.FileUtils:getInstance():purgeCachedEntries() | |||
self:saveSubGameVersion(gameId, nil) | |||
end | |||
return true | |||
end | |||
-- 能走到这里来肯定是有问题的 | |||
error("SubGameVersionManager:isNeedUpdate()") | |||
return false | |||
end | |||
-- 判断某个游戏是否正在更新中 | |||
function SubGameVersionManager:isUpdating(gameId) | |||
return self.updaterList[tonumber(gameId)] ~= nil | |||
end | |||
--- | |||
-- 获取更新任务,包含子游戏及子游戏依赖的框架,可能有多重嵌套依赖 | |||
-- @param {number} gameId 子游戏id | |||
-- @return {table} 下载任务 {{gameId = 123, isUpdated = false}, {...}} | |||
-- | |||
-- | |||
function SubGameVersionManager:getSubGameUpdateTasks (gameId) | |||
if not gameId then | |||
logE("SubGameVersionManager:getSubGameUpdateTasks", "参数gameId不能为空!") | |||
return 0 | |||
end | |||
local gameVersionInfo = app.serverConfigs:getSubGameVersionInfo(gameId) | |||
if not gameVersionInfo then | |||
-- 子游戏配置信息不存在,返回0,不下载 | |||
return 0 | |||
end | |||
local updateTasks = { | |||
{gameId = gameId, isUpdated = false}, | |||
} | |||
local subGameConfig=getSubGameConfig(gameId) | |||
while (subGameConfig and subGameConfig.fremworkId and subGameConfig.fremworkId > 0) do | |||
local isNeedUpdate = self:isNeedUpdate(subGameConfig.fremworkId) | |||
if isNeedUpdate then | |||
table.insert(updateTasks, 1, {gameId = subGameConfig.fremworkId, isUpdated = false}) | |||
end | |||
subGameConfig = getSubGameConfig(subGameConfig.fremworkId) | |||
end | |||
return updateTasks; | |||
end | |||
--- | |||
-- 更新子游戏 | |||
-- @param gameId 子游戏id | |||
-- @param percentCallback 百分比回调函数 | |||
-- @param finishCallBack 下载完成回调函数 | |||
-- @return | |||
-- | |||
function SubGameVersionManager:updateSubGame(gameId, percentCallback, finishCallBack) | |||
logD("SubGameVersionManager:updateSubGame()", gameId) | |||
local gameVersionInfo = app.serverConfigs:getSubGameVersionInfo(gameId) | |||
if not gameVersionInfo then | |||
-- 如果游戏配置不存在,直接返回 | |||
logD("游戏配置不存在,不进行更新操作!") | |||
if finishCallBack then | |||
finishCallBack(); | |||
end | |||
return | |||
end | |||
self.subGameUpdateTasks = self:getSubGameUpdateTasks(gameId) -- 需要更新的任务 | |||
self.subGameTaskCount = table.nums(self.subGameUpdateTasks) -- 需要更新的任务总数 | |||
self.curSubGameUpdateIndex = 1 -- 当前第几个任务 | |||
if self.subGameTaskCount == 0 then | |||
logD("SubGameVersionManager:updateSubGame", "没有可更新的子游戏") | |||
return | |||
end | |||
-- 开始执行子游戏更新 | |||
logD("SubGameVersionManager:updateSubGame", "开始执行子游戏更新", table.tostring(self.subGameUpdateTasks)) | |||
self:startUpdateSubGame(percentCallback, finishCallBack) | |||
end | |||
--- | |||
-- 开始执行子游戏更新 | |||
-- @param percentCallback 百分比回调函数 | |||
-- @param finishCallBack 下载完成回调函数 | |||
-- @return | |||
-- | |||
function SubGameVersionManager:startUpdateSubGame(percentCallback, finishCallBack) | |||
logD("SubGameVersionManager:startUpdateSubGame()") | |||
if table.nums(self.subGameUpdateTasks) == 0 then | |||
logD("SubGameVersionManager:startUpdateSubGame", "所有子游戏下载完成!") | |||
-- 所有任务下载完成,强制显示100% | |||
if percentCallback then | |||
percentCallback(100) | |||
end | |||
-- 所有任务下载完成,执行下载完成回调 | |||
if finishCallBack then | |||
finishCallBack() | |||
end | |||
return | |||
end | |||
local task = table.remove(self.subGameUpdateTasks, 1) | |||
logD("SubGameVersionManager:startUpdateSubGame", "开始下载子游戏,gameId:", task.gameId) | |||
if self:isNeedUpdate(task.gameId) then | |||
self:updateGame(task.gameId, function (num) | |||
-- 更新下载进度,多个任务下载时,根据当前任务索引,加上之前的下载进度 | |||
percentCallback((self.curSubGameUpdateIndex - 1) / self.subGameTaskCount * 100 + num / self.subGameTaskCount) | |||
end, function () | |||
self.curSubGameUpdateIndex = self.curSubGameUpdateIndex + 1 | |||
self:startUpdateSubGame(percentCallback, finishCallBack) | |||
end) | |||
else | |||
self:startUpdateSubGame(percentCallback, finishCallBack); | |||
end | |||
end | |||
function SubGameVersionManager:updateGame(gameId, percentCallback, finishCallBack) | |||
logD("SubGameVersionManager:updateGame", "curSubGameUpdateIndex", self.curSubGameUpdateIndex) | |||
logD("SubGameVersionManager:updateGame()", gameId) | |||
local gameVersionInfo = app.serverConfigs:getSubGameVersionInfo(gameId) | |||
gameVersionInfo.gameId = gameId | |||
--框架ID添加 | |||
if gameId > 1000 then | |||
gameVersionInfo.show = false | |||
end | |||
dump(gameVersionInfo) | |||
local function onFinishCallback(newVersion) | |||
logD("SubGameVersionManager:updateSubGame() onFinishCallback()", gameId, newVersion) | |||
-- 修改数据 | |||
self:saveSubGameVersion(gameId, newVersion) | |||
--上报游戏版本 | |||
app.php:requestReportGameVer(gameId, newVersion) | |||
-- 删除下载器 | |||
self.updaterList[gameId] = nil | |||
-- 触发回调 | |||
if finishCallBack then | |||
logD("SubGameVersionManager:updateSubGame() onFinishCallback() call finishCallBack") | |||
finishCallBack(newVersion) | |||
else | |||
logD("SubGameVersionManager:updateSubGame() onFinishCallback() finishCallBack is nil") | |||
end | |||
end | |||
local updater = import("luaScript.SubGame.SubGameUpdater"):new(gameVersionInfo, percentCallback, onFinishCallback) | |||
if updater then | |||
-- 保存下载器 | |||
self.updaterList[gameId] = updater | |||
-- 开始下载 | |||
updater:start(); | |||
end | |||
end | |||
-- 更换回调函数 | |||
function SubGameVersionManager:updateCallback(gameId, percentCallback, finishCallBack) | |||
local updater = self.updaterList[gameId] | |||
if updater then | |||
local function onFinishCallback(newVersion) | |||
logD("SubGameVersionManager:updateCallback() onFinishCallback()", gameId, newVersion) | |||
-- 修改数据 | |||
self:saveSubGameVersion(gameId, newVersion) | |||
-- 删除下载器 | |||
self.updaterList[gameId] = nil | |||
-- 触发回调 | |||
if finishCallBack then | |||
logD("SubGameVersionManager:updateCallback() onFinishCallback() call finishCallBack") | |||
finishCallBack(newVersion) | |||
else | |||
logD("SubGameVersionManager:updateCallback() onFinishCallback() finishCallBack is nil") | |||
end | |||
end | |||
updater:updateCallback(percentCallback, onFinishCallback) | |||
end | |||
end | |||
-- 获取已安装的游戏列表 | |||
function SubGameVersionManager:getGameListInstalled() | |||
local listIds | |||
-- 这里不能遍历服务器配置中的列表 | |||
-- 因为如果某个子游戏隐藏了,机器人开的房间要能进去 | |||
for k,v in pairs(GAME_IDS) do | |||
if self:isInstaller(v) then | |||
if not listIds then | |||
listIds = tostring(v) | |||
else | |||
listIds = listIds .. "," .. tostring(v) | |||
end | |||
end | |||
end | |||
return listIds; | |||
end | |||
-- local fileName = "gameUserTime.data" | |||
-- function SubGameVersionManager:loadFromFile() | |||
-- local jsonString = loadStringFromFile(fileName) | |||
-- if jsonString then | |||
-- self.info = json.decode(jsonString) or {} | |||
-- end | |||
-- end | |||
-- -- 保存信息到本地文件 | |||
-- function SubGameVersionManager:saveToFile(gameId) | |||
-- local time = os.time() | |||
-- self.info[tostring(gameId)] = time | |||
-- local jsonString = json.encode(self.info) | |||
-- saveStringToFile(jsonString, fileName) | |||
-- end | |||
function SubGameVersionManager:clearGame(gameId, endCallback) | |||
local rootName = nil | |||
local gameConfig = getSubGameConfig(gameId) | |||
if gameConfig and gameConfig.rootName then | |||
rootName = gameConfig.rootName | |||
end | |||
if FRAMEWORK_DIR[gameId] then | |||
rootName = FRAMEWORK_DIR[gameId] | |||
end | |||
if rootName then | |||
local writablePath = cc.FileUtils:getInstance():getWritablePath() | |||
if gameConfig and gameConfig.resDirs then | |||
for k,v in pairs(gameConfig.resDirs) do | |||
local dir = writablePath..app.config.RomSetting.Platform.."/"..v.."/"; | |||
logD("SubGameVersionManager:clearGame() removeDirectory, dir = ", dir); | |||
cc.FileUtils:getInstance():removeDirectory(dir) | |||
end | |||
else | |||
local dir = writablePath..app.config.RomSetting.Platform.."/"..rootName.."/"; | |||
logD("SubGameVersionManager:clearGame() removeDirectory, dir = ", dir); | |||
cc.FileUtils:getInstance():removeDirectory(dir) | |||
end | |||
self.GameVersions[gameId]=nil | |||
self:saveVersionsToFile() | |||
end | |||
app.serverConfigs:requestGetSubGameVersions(endCallback) | |||
end | |||
function SubGameVersionManager:checkSubGameFiles(gameId) | |||
logD("SubGameVersionManager:checkSubGameFiles() gameId = " .. gameId); | |||
if isWin32Platform() then | |||
return true | |||
end | |||
local rootName = nil | |||
local gameConfig = getSubGameConfig(gameId) | |||
if gameConfig and gameConfig.rootName then | |||
rootName = gameConfig.rootName | |||
end | |||
if FRAMEWORK_DIR[gameId] then | |||
rootName = FRAMEWORK_DIR[gameId] | |||
end | |||
if not rootName then | |||
return true, gameId, {} | |||
end | |||
local writablePath = cc.FileUtils:getInstance():getWritablePath() | |||
local filesfile = app.config.RomSetting.Platform .. "/" .. rootName .. "/" .. "files.txt"; | |||
logD("SubGameVersionManager:checkSubGameFiles() filesfile = ", filesfile); | |||
local result, missingfiles = checkFilesExist(filesfile) | |||
return result, gameId, missingfiles; | |||
end | |||
-- 检查子游戏文件的完整性 | |||
function SubGameVersionManager:checkGameFiles(gameId) | |||
logD("SubGameVersionManager:checkGameFiles() gameId = ", gameId); | |||
local result, subGameId, missingfiles = self:checkSubGameFiles(gameId) | |||
if not result then | |||
return result, subGameId, missingfiles | |||
end | |||
local gameConfig = getSubGameConfig(gameId) | |||
if gameConfig and gameConfig.fremworkId then | |||
logD("SubGameVersionManager:checkGameFiles() fremworkId = ", gameConfig.fremworkId); | |||
local result, subGameId, missingfiles = self:checkSubGameFiles(gameConfig.fremworkId) | |||
if not result then | |||
return result, subGameId, missingfiles | |||
end | |||
end | |||
return true, gameId, {}; | |||
end | |||
return SubGameVersionManager |
@@ -0,0 +1,143 @@ | |||
-- 子游戏更新 | |||
local SubGameUpdater = class("SubGameUpdater") | |||
--[[ | |||
gameConfig = | |||
{ | |||
version = "x.x.x.x", | |||
newVersion = | |||
{ | |||
[1] = "http://21down.dingdingqipai.com/download/bohu/release/review/1.1.4.9/", | |||
[2] = "http://120.76.202.80/download/bohu/release/review/1.1.4.9/", | |||
}, | |||
} | |||
percentCallback : 更新进度的回调 | |||
finishCallBack : 更新完成的回调 | |||
--]] | |||
local writablePath = cc.FileUtils:getInstance():getWritablePath() | |||
function SubGameUpdater:ctor(gameVersionInfo, percentCallback, finishCallBack) | |||
logI("SubGameUpdater:ctor()", table.tostring(gameConfig)) | |||
if not gameVersionInfo then | |||
return | |||
end | |||
-- 配置信息 | |||
self.gameVersionInfo = gameVersionInfo; | |||
-- 更新进度的回调 | |||
self.percentCallback = percentCallback | |||
-- 更新完成的回调 | |||
self.finishCallBack = finishCallBack | |||
self.gameId = self.gameVersionInfo.gameId | |||
self.newVersion = self.gameVersionInfo.ver | |||
local tempDir = os.date("%Y%m%d%H%M%S", os.time()); | |||
local tempFile = string.format("tempGameFile%d.zip",self.gameId) | |||
self.zipFileDir = writablePath .. tempDir .. '/'; | |||
self.zipFilePath = self.zipFileDir .. tempFile; | |||
if not cc.FileUtils:getInstance():isDirectoryExist(self.zipFileDir) then | |||
if not cc.FileUtils:getInstance():createDirectory(self.zipFileDir) then | |||
logD("SubGameUpdater:ctor() createDirectory failed :" .. self.zipFileDir) | |||
end | |||
end | |||
logD("SubGameUpdater:ctor() self.zipFileDir = ", self.zipFileDir) | |||
logD("SubGameUpdater:ctor() self.zipFilePath = ", self.zipFilePath) | |||
end | |||
-- 更新回调,替换之前的 | |||
function SubGameUpdater:updateCallback(percentCallback, finishCallBack) | |||
-- 更新进度的回调 | |||
self.percentCallback = percentCallback | |||
-- 更新完成的回调 | |||
self.finishCallBack = finishCallBack | |||
end | |||
-- 开始更新 | |||
function SubGameUpdater:start() | |||
logD("SubGameUpdater:start()") | |||
local function onState(state,msg) | |||
logD("SubGameUpdater:start() onState()", state, msg) | |||
if state=="progress" then | |||
local percent = msg*100 | |||
-- 回调更新进度 | |||
self:onUpdatePercent(percent) | |||
elseif state=="successed" then | |||
local percent = 100 | |||
-- 回调更新进度 | |||
self:onUpdatePercent(percent) | |||
runDelayWithTime(function() | |||
self:onFinishDownZip() | |||
end,0.01) | |||
end | |||
end | |||
downloadFileByUrls2(self.gameVersionInfo.url, onState, self.zipFilePath) | |||
end | |||
function SubGameUpdater:onFinishDownZip() | |||
logD("SubGameUpdater:onFinishDownZip()") | |||
local md5=cc.FileUtils:getInstance():md5File(self.zipFilePath) | |||
if md5~=self.gameVersionInfo.md5 then | |||
os.remove(self.zipFilePath) | |||
logE("md5 不对!"..md5.."!="..self.gameVersionInfo.md5) | |||
showTooltip("文件数据不正确!请尝试重新下载!") | |||
-- self:dispatchEvent("error",PLN.FILE_CHECKSUM_FAILED) | |||
return | |||
end | |||
-- self:dispatchEvent("zip",{text=PLN.UPDATING_RES,percent=1}) | |||
local isZipSuccessed=cc.FileUtils:getInstance():decompress(self.zipFilePath) | |||
os.remove(self.zipFilePath) | |||
if isZipSuccessed then | |||
local move_result = move_dir(self.zipFileDir, writablePath); | |||
if move_result then | |||
remove_dir(self.zipFileDir) | |||
self:onUpdateFinish() | |||
else | |||
logD("SubGameUpdater:onFinishDownZip() move_dir failed"); | |||
end | |||
else | |||
logD("SubGameUpdater:onFinishDownZip() unzip failed"); | |||
end | |||
end | |||
-- 更新进度 | |||
function SubGameUpdater:onUpdatePercent (percent) | |||
if self.percentCallback then | |||
self.percentCallback(percent) | |||
end | |||
end | |||
-- 更新完成 | |||
function SubGameUpdater:onUpdateFinish(jsonFileData) | |||
logD("SubGameUpdater:onUpdateFinish()", self.gameId, self.newVersion) | |||
-- 保存最新的update.json文件 | |||
-- logD("保存json:"..jsonFileData) | |||
-- saveStringToFile(jsonFileData, self.clientUpdateFile); | |||
--清除更新数据 | |||
self.gameVersionInfo.url="" | |||
-- 通知回调 | |||
if self.finishCallBack then | |||
self.finishCallBack(self.newVersion) | |||
end | |||
end | |||
return SubGameUpdater |
@@ -0,0 +1,30 @@ | |||
-- 游戏玩法类型 | |||
GAME_TYPE = | |||
{ | |||
PK = 1, -- 扑克 | |||
ZP = 2, -- 字牌 | |||
MJ = 3, -- 麻将 | |||
} | |||
-- 游戏玩法类型描述 | |||
GAME_TYPE_NAME = | |||
{ | |||
[GAME_TYPE.PK] = "扑克", | |||
[GAME_TYPE.ZP] = "字牌", | |||
[GAME_TYPE.MJ] = "麻将", | |||
} | |||
-- 基础包的目录 | |||
FRAMEWORK_DIR = | |||
{ | |||
[1001] = "mj", | |||
[1002] = "zp", | |||
[1003] = "pk", | |||
} | |||
-- 游戏ID | |||
GAME_IDS = | |||
{ | |||
-- More = 0, -- 更多 | |||
} |
@@ -0,0 +1,215 @@ | |||
require("luaScript.SubGameConfigs") | |||
-- 获取子游戏的配置信息 | |||
function getSubGameConfig(gameId) | |||
local gameId = tonumber(gameId) | |||
logD("getSubGameConfig:"..gameId) | |||
local gameConfig = app.subGameConfigManager:getSubGameConfig(gameId) | |||
if not gameConfig then | |||
gameConfig = app.config.SubGameConfigs[gameId] | |||
end | |||
return gameConfig; | |||
end | |||
-- 获取子游戏的名称 | |||
-- 名称来自服务器的配置 | |||
function getSubGameName(gameId) | |||
local gameId = tonumber(gameId) | |||
logD("getSubGameName:"..gameId) | |||
local gameConfig = getSubGameConfig(gameId) | |||
if gameConfig then | |||
return gameConfig.gameName or "" | |||
end | |||
end | |||
-- 获取子游戏的大厅类 | |||
function getSubGameMainView(gameId) | |||
local gameId = tonumber(gameId) | |||
logD("getSubGameMainView:"..gameId) | |||
local gameConfig = getSubGameConfig(gameId) | |||
if not gameConfig then | |||
logE("Error :: getSubGameMainView() 没有找到对应的子游戏配置信息, ", gameId) | |||
return nil | |||
end | |||
return gameConfig.mainViewName | |||
end | |||
-- 获取子游戏的房间类 | |||
-- 由于历史原因,房间内可能根据玩法不一样存在多个 | |||
function getSubGameRoomView(gameId, gameRule, protocolType) | |||
local gameId = tonumber(gameId) | |||
local gameRule = tonumber(gameRule) | |||
logD("getSubGameRoomView:"..gameId) | |||
local gameConfig = getSubGameConfig(gameId) | |||
if not gameConfig then | |||
logE("Error :: getSubGameRoomView() 没有找到对应的子游戏配置信息, ", gameId, gameRule) | |||
return nil | |||
end | |||
local roomViewName = gameConfig.roomViewName | |||
if protocolType == PROTOCOL_TYPE.COIN then | |||
roomViewName = gameConfig.roomViewNameCoin or roomViewName; | |||
elseif protocolType == PROTOCOL_TYPE.MATCH then | |||
roomViewName = gameConfig.roomViewNameMatch or roomViewName; | |||
end | |||
if roomViewName and type(roomViewName) == "table" then | |||
return roomViewName[gameRule] | |||
else | |||
return roomViewName; | |||
end | |||
end | |||
--- getSubGameProtocolClass 获取子游戏的协议类 | |||
-- 由于历史原因,协议类可能根据玩法不一样存在多个 | |||
-- @param gameId 游戏id | |||
-- @param gameRule 游戏玩法 | |||
-- @param protocolType 协议类型 | |||
function getSubGameProtocolClass(gameId, gameRule, protocolType) | |||
local gameId = tonumber(gameId) | |||
local gameRule = tonumber(gameRule) | |||
logD("getSubGameProtocolClass:"..gameId) | |||
local gameConfig = getSubGameConfig(gameId) | |||
if not gameConfig then | |||
logE("Error :: getSubGameProtocolClass() 没有找到对应的子游戏配置信息, ", gameId, gameRule) | |||
return nil | |||
end | |||
local protocolClass = gameConfig.protocolClass; | |||
if protocolType == PROTOCOL_TYPE.COIN then | |||
protocolClass = gameConfig.protocolClassCoin or protocolClass; | |||
elseif protocolType == PROTOCOL_TYPE.MATCH then | |||
protocolClass = gameConfig.protocolClassMatch or protocolClass; | |||
end | |||
if protocolClass and type(protocolClass) == "table" then | |||
return protocolClass[gameRule] | |||
else | |||
return protocolClass; | |||
end | |||
end | |||
-- 获取子游戏的战绩协议类 | |||
function getSubGameProtocolZhanJi(gameId) | |||
local gameId = tonumber(gameId) | |||
logD("getSubGameProtocolZhanJi:"..gameId) | |||
local gameConfig = getSubGameConfig(gameId) | |||
if not gameConfig then | |||
logE("Error :: getSubGameProtocolZhanJi() 没有找到对应的子游戏配置信息, ", gameId) | |||
return nil | |||
end | |||
return gameConfig.protocolZhanJi | |||
end | |||
-- 获取子游戏的战绩单局界面 | |||
function getSubGameZhanjiDanJuView(gameId) | |||
local gameId = tonumber(gameId) | |||
logD("getSubGameZhanjiDanJuView:"..gameId) | |||
local gameConfig = getSubGameConfig(gameId) | |||
if not gameConfig then | |||
logE("Error :: getSubGameZhanjiView() 没有找到对应的子游戏配置信息, ", gameId) | |||
return nil | |||
end | |||
return gameConfig.zhanjiDanjuView | |||
end | |||
-- 获取子游戏创建房间界面的规则ui | |||
function getSubGameCreateRoomUi(gameId, gameRule) | |||
local gameId = tonumber(gameId) | |||
local gameRule = tonumber(gameRule) | |||
logD("getSubGameCreateRoomUi:"..gameId) | |||
local gameConfig = getSubGameConfig(gameId) | |||
if not gameConfig then | |||
logE("Error :: getSubGameProtocolClass() 没有找到对应的子游戏配置信息, ", gameId, gameRule) | |||
return nil | |||
end | |||
if gameConfig.uiCreateRule and type(gameConfig.uiCreateRule) == "table" then | |||
return gameConfig.uiCreateRule[gameRule] or gameConfig.uiCreateRule[tostring(gameRule)] | |||
else | |||
return nil | |||
end | |||
end | |||
-- 获取子游戏玩法的名字 | |||
function getSubGameRuleName(gameId, gameRule) | |||
local gameId = tonumber(gameId) | |||
local gameRule = tonumber(gameRule) | |||
logD("getSubGameRuleName:"..gameId) | |||
local gameConfig = getSubGameConfig(gameId) | |||
if not gameConfig then | |||
logE("Error :: getSubGameRuleName() 没有找到对应的子游戏配置信息, ", gameId, gameRule) | |||
return "" | |||
end | |||
if gameConfig.GameType and type(gameConfig.GameType) == "table" then | |||
return gameConfig.GameType[gameRule] or gameConfig.GameType[tostring(gameRule)] | |||
else | |||
return "" | |||
end | |||
end | |||
-- 获取子游戏玩法的人数 | |||
function getSubGamePlayerNum(gameId, gameRule) | |||
local gameId = tonumber(gameId) | |||
local gameRule = tonumber(gameRule) | |||
logD("getSubGamePlayerNum:"..gameId) | |||
local gameConfig = getSubGameConfig(gameId); | |||
if not gameConfig or not gameConfig.playerNum then | |||
return | |||
end | |||
return gameConfig.playerNum[gameRule] or gameConfig.playerNum[tostring(gameRule)] or 4 | |||
end | |||
-- 获取子游戏的战绩回放界面 | |||
function getSubGameZhanjiRecordView(gameId) | |||
local gameId = tonumber(gameId) | |||
logD("getSubGameZhanjiRecordView:"..gameId) | |||
local gameConfig = getSubGameConfig(gameId) | |||
if not gameConfig then | |||
logE("Error :: getSubGameZhanjiRecordView() 没有找到对应的子游戏配置信息, ", gameId) | |||
return nil | |||
end | |||
return gameConfig.zhanjiRecordView | |||
end | |||
-- 获取子游戏的桌面水印 | |||
-- 可能返回""或者nil | |||
function getSubGameRoomLogo(gameId, ruleId) | |||
logD("getSubGameRoomLogo() gameId = "..tostring(gameId) .. ", ruleId = "..tostring(ruleId)) | |||
if not gameId or not ruleId then | |||
error("") | |||
return; | |||
end | |||
local gameId = tonumber(gameId) | |||
local ruleId = tonumber(ruleId) | |||
local gameConfig = getSubGameConfig(gameId) | |||
if not gameConfig then | |||
logE("Error :: getSubGameRoomLogo() 没有找到对应的子游戏配置信息 ", gameId, ruleId) | |||
return nil | |||
end | |||
if not gameConfig.room_logos then | |||
logE("Error :: getSubGameRoomLogo() 没有找到对应的水印配置信息") | |||
return nil | |||
end | |||
return gameConfig.room_logos[ruleId] or gameConfig.room_logos[tostring(ruleId)] | |||
end | |||
-- 获取子游戏创建房间界面的配置 | |||
function getSubGameCreateRuleConfig(gameId) | |||
local gameConfig = getSubGameConfig(gameId) | |||
if gameConfig then | |||
return gameConfig.createRule | |||
else | |||
return nil | |||
end | |||
end |
@@ -0,0 +1,86 @@ | |||
--获取创建房间选项配置 | |||
function getRuleFromString(gameId, jushu, ruleStr) | |||
local config=getSubGameConfig(tonumber(gameId)) | |||
if type(config.wanfaConfig) == "string" then | |||
local isRequired, wanfa = pcall(require, config.wanfaConfig) | |||
if isRequired and wanfa and type(wanfa.getRuleFromString) == "function" then | |||
local tt = wanfa.getRuleFromString(gameId, jushu, ruleStr) | |||
return tt or {} | |||
end | |||
end | |||
local tt = {} | |||
local jsonData = json.decode(ruleStr); | |||
--"{\"kun\":14,\"gamerule\":0,\"baozi\":10,\"minHuShu\":18,\"specRule\":1}", | |||
-- 局数 | |||
local jushuText = string.format("%d 局",jushu); | |||
table.insert(tt, {name = "局数", value = {jushuText}}) | |||
--判断游戏配置是麻将 | |||
local config=getSubGameConfig(tonumber(gameId)) | |||
if config and config.belongType==3 then | |||
if jsonData.deductRule and jsonData.deductRule >= 0 then | |||
local specStr =jsonData.deductRule==0 and "房主付费" or "AA付费" | |||
if specStr ~= "" then | |||
table.insert(tt, {name = "房费", value = {specStr}}) | |||
end | |||
end | |||
local MJWanFa=MJFramework.ImportWanFa("luaScript.SubGameDefine.MaJiang.MJWanFa",tonumber(gameId)) | |||
table.insertTo(tt,MJWanFa.getClubWaFaInfo(ruleStr)) | |||
elseif config and config.belongType==2 then | |||
if jsonData.deductRule and jsonData.deductRule >= 0 then | |||
local specStr =jsonData.deductRule==0 and "房主付费" or "AA付费" | |||
if specStr ~= "" then | |||
table.insert(tt, {name = "房费", value = {specStr}}) | |||
end | |||
end | |||
--[[-- 是否已下载 | |||
local isDownGame = app.subGameManager:isInstaller(tonumber(gameId)) | |||
-- 是否需要更新 | |||
local isUpdate = app.subGameManager:isNeedUpdate(tonumber(gameId)) | |||
if isDownGame == false or isUpdate == true then | |||
return tt | |||
end--]] | |||
local ZPWanFa = ZPFramework.ImportWanFa("luaScript.SubGameDefine.ZiPai.ZPWanFa",gameId) | |||
table.insertTo(tt,ZPWanFa.getClubRuleInfo(ruleStr)) | |||
end | |||
return tt; | |||
end | |||
--获取包间多玩法桌子上显示的信息 | |||
function getClubTableRuleString(gameId, ruleStr) | |||
--判断游戏配置是麻将 | |||
local str ="" | |||
local config=getSubGameConfig(tonumber(gameId)) | |||
if type(config.wanfaConfig) == "string" then | |||
local isRequired, wanfa = pcall(require, config.wanfaConfig) | |||
if isRequired and wanfa and type(wanfa.getClubTableRuleString) == "function" then | |||
local str = wanfa.getClubTableRuleString(gameId, ruleStr, playerNum) | |||
return str or "" | |||
end | |||
end | |||
if config and config.belongType==3 then | |||
local MJWanFa=MJFramework.ImportWanFa("luaScript.SubGameDefine.MaJiang.MJWanFa",gameId) | |||
str = MJWanFa.getClubTableWanFaInfo(ruleStr) | |||
elseif config and config.belongType==2 then | |||
local ZPWanFa = ZPFramework.ImportWanFa("luaScript.SubGameDefine.ZiPai.ZPWanFa",gameId) | |||
str = ZPWanFa.getClubTableWanFaInfo(ruleStr) | |||
end | |||
if tonumber(gameId) == GAME_IDS.luzhouPaoDeKuai then | |||
local lzPDKDefine = require("luaScript.SubGameDefine.luzhouPDKDefine") | |||
str = lzPDKDefine.getClubTableWanFaInfo(ruleStr) | |||
elseif tonumber(gameId) == GAME_IDS.hejiangPaoDeKuai then | |||
local hjPDKDefine = require("luaScript.SubGameDefine.hejiangPDKDefine") | |||
str = hjPDKDefine.getClubTableWanFaInfo(ruleStr) | |||
end | |||
return str; | |||
end |
@@ -0,0 +1,54 @@ | |||
-- 定义动画状态机 | |||
AnimEntityStatus = | |||
{ | |||
[1] = | |||
{ | |||
stateName = "death", | |||
stateValues = | |||
{ | |||
[1] = {animation = "death" , loop = false , staticWhenEnd = true}; | |||
}; | |||
}; | |||
[2] = | |||
{ | |||
stateName = "skill", | |||
stateValues = | |||
{ | |||
[1] = {animation = "spell" , loop = false}; | |||
[2] = {animation = "spell2" , loop = false}; | |||
}; | |||
}; | |||
[3] = | |||
{ | |||
stateName = "attack", | |||
stateValues = | |||
{ | |||
[1] = {animation = "attack" , loop = false}; | |||
}; | |||
}; | |||
[4] = | |||
{ | |||
stateName = "move", | |||
stateValues = | |||
{ | |||
[0] = {animation = "stand" , loop = true , randomPosition = true}; | |||
[1] = {animation = "walk" , loop = true , randomPosition = true}; | |||
[2] = {animation = "walk2" , loop = true , randomPosition = true}; | |||
}; | |||
} | |||
} | |||
cc.AnimEntityUtils:getInstance():setAnimGroupSet(AnimEntityStatus) | |||
-- 创建英雄动画实例 | |||
function createHeroEntity(skeleton) | |||
if type(skeleton.createAnimEntity) == "function" then | |||
skeleton:createAnimEntity() | |||
local animEntity = skeleton:getAnimEntity(); | |||
-- 默认播放站立动画 | |||
animEntity:updateState("move", 0); | |||
return animEntity | |||
end | |||
return nil | |||
end |
@@ -0,0 +1,180 @@ | |||
local CheckBoxManager = class("CheckBoxManager") | |||
--[[ | |||
复选框管理器 | |||
使用方法: | |||
使用接口addItem,传入 checkBox 及对应的key,选中值,非选中值, | |||
不需要关注每个 checkBox 的点击事件 | |||
玩家操作完之后,使用接口 getResult 获取最后的结果 | |||
所有被选中的 checkBox 对应的 value 会被放在一个 table 中返回 | |||
]]-- | |||
local normalColor = cc.c4b(21,99,97,255) | |||
local selectColor = cc.c4b(213,46,11,255) | |||
function CheckBoxManager:ctor() | |||
self.numCheckBox = 0; | |||
self.listCheckBox = {} | |||
self.callback = nil | |||
self.colorSwitch = true | |||
end | |||
-- 添加点击时的回调 | |||
function CheckBoxManager:setColorSwitch(colorSwitch) | |||
self.colorSwitch = colorSwitch; | |||
end | |||
function CheckBoxManager:addItem(checkBox, key,selectValue,noSelectValue) | |||
if not checkBox then | |||
return | |||
end | |||
-- 数量自增 | |||
self.numCheckBox = self.numCheckBox + 1 | |||
local index = self.numCheckBox; | |||
self.listCheckBox[index] = {node = checkBox, key = key, selectValue = selectValue ,noSelectValue = noSelectValue}; | |||
-- 注册点击事件 | |||
checkBox:registerClick(function() | |||
self:onClickCheckBos(index,true) | |||
end) | |||
-- 子节点响应点击事件 | |||
local children = checkBox:getChildren(); | |||
for i, k in pairs(children) do | |||
k:setTouchEnabled(true) | |||
k:registerClick(function() | |||
self:onClickCheckBos(index,false) | |||
end) | |||
end | |||
end | |||
-- 设置默认状态 | |||
function CheckBoxManager:setDefault(keyList) | |||
for idx, key in pairs(keyList) do | |||
for k,v in pairs(self.listCheckBox) do | |||
if key == v.key and v.node then | |||
v.node:setSelectedState(true) | |||
local children = v.node:getChildren(); | |||
for i, k in pairs(children) do | |||
if self.colorSwitch then | |||
k:setTextColor(selectColor) | |||
end | |||
end | |||
end | |||
end | |||
end | |||
end | |||
--[[ | |||
返回Key和当前checkbox状态对应的值 | |||
]] | |||
function CheckBoxManager:getResult() | |||
local tt = {} | |||
for k,v in pairs(self.listCheckBox) do | |||
if v.node then | |||
tt[v.key] = {} | |||
if v.node:getSelectedState() then | |||
tt[v.key].value = v.selectValue | |||
tt[v.key].key = v.key | |||
else | |||
tt[v.key].value = v.noSelectValue | |||
tt[v.key].key = nil | |||
end | |||
end | |||
end | |||
return tt; | |||
end | |||
function CheckBoxManager:getResult2() | |||
local tt = {} | |||
for k,v in pairs(self.listCheckBox) do | |||
if v.node then | |||
if v.node:getSelectedState() then | |||
tt[v.key] = v.selectValue | |||
else | |||
tt[v.key] = v.noSelectValue | |||
end | |||
end | |||
end | |||
return tt; | |||
end | |||
-- 添加点击时的回调 | |||
function CheckBoxManager:setCallback(callback) | |||
self.callback = callback; | |||
end | |||
-- | |||
function CheckBoxManager:onClickCheckBos(index, fromTouch) | |||
--[[if fromTouch then | |||
playBtnEffect() | |||
end--]] | |||
playBtnEffect() | |||
self.curCheckBox = index | |||
if not fromTouch then | |||
local state = self.listCheckBox[self.curCheckBox].node:getSelectedState() | |||
self.listCheckBox[self.curCheckBox].node:setSelectedState(not state) | |||
local children = self.listCheckBox[self.curCheckBox].node:getChildren(); | |||
for i, k in pairs(children) do | |||
if not state then | |||
if self.colorSwitch then | |||
k:setTextColor(selectColor) | |||
end | |||
else | |||
if self.colorSwitch then | |||
k:setTextColor(normalColor) | |||
end | |||
end | |||
end | |||
else | |||
local state = self.listCheckBox[self.curCheckBox].node:getSelectedState() | |||
local children = self.listCheckBox[self.curCheckBox].node:getChildren(); | |||
for i, k in pairs(children) do | |||
if not state then | |||
if self.colorSwitch then | |||
k:setTextColor(selectColor) | |||
end | |||
else | |||
if self.colorSwitch then | |||
k:setTextColor(normalColor) | |||
end | |||
end | |||
end | |||
end | |||
local state = self.listCheckBox[self.curCheckBox].node:getSelectedState() | |||
-- 回调 | |||
runDelay(0.1,function () | |||
if self.callback then | |||
self.callback() | |||
end | |||
end) | |||
end | |||
function CheckBoxManager:setSelectedState(key,state) | |||
for k,v in pairs(self.listCheckBox) do | |||
if key == v.key and v.node then | |||
v.node:setSelectedState(state) | |||
local children = v.node:getChildren(); | |||
for i, k in pairs(children) do | |||
if self.colorSwitch then | |||
k:setTextColor(state and selectColor or normalColor) | |||
end | |||
end | |||
end | |||
end | |||
end | |||
return CheckBoxManager |
@@ -0,0 +1,254 @@ | |||
--[[ | |||
金币动画播放器 | |||
使用方法: | |||
local coinPlayer = import("luaScript.Tools.CoinAniPlayer"):new() | |||
if coinPlayer then | |||
local nodeBegin = self.ui.Items.Button_AddDiamand | |||
local nodeEnd = self.ui.Items.Button_KeFu | |||
local goldNum = 100 | |||
local goldIcon = "jinbi.png" | |||
local endCallback = function() | |||
showTooltip("onEnd") | |||
end | |||
local sizeRange = cc.size(50, 50) | |||
coinPlayer:playAnimation(nodeBegin, nodeEnd, goldNum, goldIcon, endCallback, sizeRange); | |||
end | |||
--]] | |||
local CoinAniPlayer = class("CoinAniPlayer") | |||
function CoinAniPlayer:ctor(goldIcon) | |||
self.goldIcon = goldIcon | |||
--初始化金币池 | |||
self:initCoinPool() | |||
end | |||
--[[ | |||
金币对象池 | |||
]] | |||
function CoinAniPlayer:initCoinPool() | |||
local maxCoin = 200 | |||
--金币缓冲池 | |||
self.coinList = {} | |||
--金币激活池 | |||
--self.coinActiveList = {} | |||
--延迟加载创建金币 | |||
for i = 1 ,maxCoin do | |||
local seq = cc.Sequence:create(cc.DelayTime:create(i * 0.01),cc.CallFunc:create(function () | |||
local outCoin = cc.ImageView:createNode() | |||
outCoin:loadTextureFromPlist(self.goldIcon) | |||
app.mainScene:addChild(outCoin) | |||
local randomX = math.random(-34,34) | |||
local randomY = math.random(-34,34) | |||
outCoin:setPosition(cc.p(640+ randomX,360+ randomY)) | |||
outCoin:setVisible(false) | |||
outCoin:retain() | |||
table.insert(self.coinList,outCoin) | |||
if i == maxCoin then | |||
--showTooltip("初始化金币池完成") | |||
end | |||
end)) | |||
app.mainScene:runAction(seq) | |||
end | |||
end | |||
--取出一个金币 | |||
function CoinAniPlayer:takeOutCoin() | |||
local object | |||
if table.nums(self.coinList) > 0 then | |||
object = self.coinList[1] | |||
table.remove(self.coinList,1) | |||
else | |||
--立马创建 | |||
for i = 1 ,60 do | |||
local outCoin = cc.ImageView:createNode() | |||
outCoin:loadTextureFromPlist(self.goldIcon) | |||
app.mainScene:addChild(outCoin) | |||
local randomX = math.random(-34,34) | |||
local randomY = math.random(-34,34) | |||
outCoin:setPosition(cc.p(640+ randomX,360+ randomY)) | |||
outCoin:setVisible(false) | |||
outCoin:retain() | |||
table.insert(self.coinList,outCoin) | |||
end | |||
object = self.coinList[1] | |||
table.remove(self.coinList,1) | |||
print("对象池不够了,创建新的金币") | |||
--showTooltip("对象池不够了,创建新的金币") | |||
end | |||
return object | |||
end | |||
--放回一个金币 | |||
function CoinAniPlayer:pushCoinPool(coin) | |||
--coin:release() | |||
--重置精灵的状态 | |||
coin:setVisible(false) | |||
coin:setOpacity(255) | |||
--坐标可以设置或者不设置都可以 | |||
local randomX = math.random(-34,34) | |||
local randomY = math.random(-34,34) | |||
coin:setPosition(cc.p(640+ randomX,360+ randomY)) | |||
table.insert(self.coinList,coin) | |||
--logD("pushCoinPool num:"..table.nums(self.coinList)) | |||
end | |||
--[[ | |||
金币动画 | |||
nodeBegin : 起始点 | |||
nodeEnd : 结束点 | |||
goldNum : 金币数量 | |||
goldIcon : 金币图标 | |||
endCallback : 动画完成后的回调 | |||
sizeRange : 范围大小 | |||
--]] | |||
function CoinAniPlayer:playAnimation(nodeBegin, nodeEnd, goldNum, voiceName,endCallback, sizeRange) | |||
local posBegin = nodeBegin:getWorldPosition() | |||
local posEnd = nodeEnd:getWorldPosition() | |||
local goldNum = goldNum or 0 | |||
if sizeRange then | |||
self:_playAnimationR2R(posBegin, posEnd, goldNum, voiceName,endCallback, sizeRange) | |||
else | |||
self:_playAnimationP2P(posBegin, posEnd, goldNum, voiceName,endCallback) | |||
end | |||
end | |||
--[[ | |||
金币动画点到点 | |||
nodeBegin : 起始点 | |||
nodeEnd : 结束点 | |||
goldNum : 金币数量 | |||
goldIcon : 金币图标 - 从SpriteFrameCacha中读取 | |||
endCallback : 动画完成后的回调 | |||
--]] | |||
function CoinAniPlayer:_playAnimationP2P(posBegin, posEnd, goldNum,voiceName,endCallback) | |||
--local moveTime = 0.6 | |||
--local moveTime = 0.45 | |||
local moveTime = 0.47 | |||
local intrval = 0.08 | |||
local coinMax = 25 | |||
if goldNum == 24 then | |||
goldNum = 18 | |||
elseif goldNum == 12 then | |||
goldNum = 8 | |||
end | |||
if goldNum > 8 then | |||
intrval = 0.06 | |||
end | |||
if goldNum > coinMax then | |||
goldNum = 22 | |||
end | |||
local numCoin = self:_getCoinNum(goldNum) | |||
voiceName = voiceName or "res/sound/room/ph_coin.ogg" | |||
for i = 1, numCoin do | |||
local spCoin = self:takeOutCoin() | |||
if spCoin then | |||
-- 设置起始位置 | |||
spCoin:setVisible(true) | |||
spCoin:setAnchorPoint(cc.p(0.5, 0.5)) | |||
spCoin:setPosition(posBegin) | |||
-- 延迟 - 淡入 - 移动 - 回调 | |||
local function onPlayEnd() | |||
-- 丢回对象池 | |||
self:pushCoinPool(spCoin) | |||
-- 如果是最后一个金币播放完成,则通知回调 | |||
if i == numCoin then | |||
if endCallback then | |||
endCallback() | |||
end | |||
end | |||
end | |||
local spawn = cc.Spawn:create( | |||
cc.MoveTo:create(moveTime, cc.p(posEnd.x, posEnd.y)), | |||
cc.ScaleTo:create(moveTime, 1.0),cc.CallFunc:create(function() | |||
playVoice(voiceName) | |||
end)); | |||
local seq = cc.Sequence:create( | |||
cc.DelayTime:create(i * intrval), | |||
cc.FadeIn:create(0.01), | |||
cc.EaseSineOut:create(spawn), | |||
--spawn, | |||
cc.CallFunc:create(onPlayEnd)); | |||
spCoin:runAction(seq) | |||
end | |||
end | |||
end | |||
--[[ | |||
金币动画范围到范围 | |||
nodeBegin : 起始点 | |||
nodeEnd : 结束点 | |||
goldNum : 金币数量 | |||
goldIcon : 金币图标 | |||
endCallback : 动画完成后的回调 | |||
sizeRange : 范围大小 | |||
--]] | |||
function CoinAniPlayer:_playAnimationR2R(posBegin, posEnd, goldNum, voiceName ,endCallback, sizeRange) | |||
local moveTime = 1.0 | |||
local numCoin = self:_getCoinNum(goldNum) | |||
voiceName = voiceName or "res/sound/room/ph_coin.ogg" | |||
for i = 1, numCoin do | |||
local spCoin = self:takeOutCoin() | |||
if spCoin then | |||
spCoin:setVisible(true) | |||
-- 随机起始点 | |||
local randomX = math.random(-sizeRange.width / 2, sizeRange.width / 2) | |||
local randomY = math.random(-sizeRange.height / 2, sizeRange.height / 2) | |||
local posBegin = cc.p(posBegin.x + randomX, posBegin.y + randomY ) | |||
-- 随机结束点 | |||
local randomX = math.random(-sizeRange.width / 2, sizeRange.width / 2) | |||
local randomY = math.random(-sizeRange.height / 2, sizeRange.height / 2) | |||
local posEnd = cc.p(posEnd.x + randomX, posEnd.y + randomY ) | |||
-- 设置起始位置 | |||
spCoin:setAnchorPoint(cc.p(0.5, 0.5)) | |||
spCoin:setPosition(posBegin) | |||
-- 延迟 - 淡入 - 移动 - 回调 | |||
local function onPlayEnd() | |||
-- 丢回对象池 | |||
self:pushCoinPool(spCoin) | |||
-- 如果是最后一个金币播放完成,则通知回调 | |||
if i == numCoin then | |||
if endCallback then | |||
endCallback() | |||
end | |||
end | |||
end | |||
local spawn = cc.Spawn:create( | |||
cc.MoveTo:create(moveTime, cc.p(posEnd.x, posEnd.y)), | |||
cc.ScaleTo:create(moveTime, 1.0),cc.CallFunc:create(function() | |||
playVoice(voiceName) | |||
end)); | |||
local seq = cc.Sequence:create( | |||
cc.DelayTime:create(i * 0.01), | |||
cc.FadeIn:create(0.01), | |||
cc.EaseSineOut:create(spawn), | |||
cc.CallFunc:create(onPlayEnd)); | |||
spCoin:runAction(seq) | |||
end | |||
end | |||
end | |||
-- 获取需要创建的金币图标的个数 | |||
function CoinAniPlayer:_getCoinNum(num) | |||
if num then | |||
return num | |||
else | |||
return 10 | |||
end | |||
end | |||
return CoinAniPlayer |
@@ -0,0 +1,372 @@ | |||
function toboolean(str) | |||
return str == "1" or str == "true" or str == 1 or str == true; | |||
end | |||
-- 把字符串转换成数组,并用itemConvertFunc转换所有元素 | |||
function toArray(szSeparator , itemConvertFunc) | |||
return function(str) | |||
local strs = string.split(str , szSeparator) | |||
if itemConvertFunc then | |||
local items = {} | |||
for i , v in ipairs(strs) do | |||
table.insert(items , itemConvertFunc(v)) | |||
end | |||
return items; | |||
else | |||
return strs; | |||
end | |||
end | |||
end | |||
function createEvalFunction(evalFunction , exp) | |||
local evalTable = {} | |||
evalTable.__call = function(self , ...)return evalFunction(...)end; | |||
evalTable.__index = evalTable; | |||
evalTable.exp = exp; | |||
setmetatable(evalTable , evalTable); | |||
return evalTable; | |||
end | |||
-- 把公式字符串转换成返回整数的函数, 结果是小数的情况就用向上取整 | |||
function toInterEval(str) | |||
local function _tmp(...) | |||
local arg = {...} | |||
local env = {}; | |||
local index = 1; | |||
for k, v in pairs(arg) do | |||
env["x" .. index] = v; | |||
index = index + 1; | |||
end | |||
return evalServerScript(str ,env) | |||
end | |||
local function retFunc(...) | |||
local value = _tmp(...); | |||
--return math.ceil(value); | |||
-- 是否取整由使用者决定吧 | |||
return value; | |||
end | |||
return createEvalFunction(retFunc , str); | |||
end | |||
-- 把公式字符串转换成lua函数 | |||
function toEval(str) | |||
local function retFunc(...) | |||
local arg = {...} | |||
local env = {}; | |||
local index = 1; | |||
for k, v in pairs(arg) do | |||
env["x" .. index] = v; | |||
index = index + 1; | |||
end | |||
return evalServerScript(str ,env) | |||
end | |||
return createEvalFunction(retFunc , str); | |||
end; | |||
-- 把字符串转换成数值数组 | |||
function _toMultiArray(startIndex , ...) | |||
local arg = {...} | |||
if #arg == startIndex then | |||
local desc = arg[startIndex]; | |||
return toArray(desc.sep , desc.converter); | |||
else | |||
local function run(str) | |||
local desc = arg[startIndex]; | |||
local item = string.split(str , desc.sep) | |||
local index = startIndex + 1; | |||
for ii , vv in ipairs(item) do | |||
item[ii] = _toMultiArray(index , unpack(arg))(vv); | |||
end | |||
return item; | |||
end | |||
return run; | |||
end | |||
end | |||
-- 把字符串转换成多维数组 | |||
function toStringArray(...) | |||
local arg = {...} | |||
local numArg = {}; | |||
for i , v in ipairs(arg) do | |||
numArg[i] = {sep = v , converter = nil}; | |||
end | |||
return _toMultiArray(1 , unpack(numArg)); | |||
end | |||
-- 把字符串转换成数值数组 | |||
function toNumberArray(...) | |||
local arg = {...} | |||
local numArg = {}; | |||
for i , v in ipairs(arg) do | |||
numArg[i] = {sep = v , converter = tonumber}; | |||
end | |||
return _toMultiArray(1 , unpack(numArg)); | |||
end | |||
-- 把字符串转换成数值数组 | |||
function autoMultiArray(str) | |||
local run = nil; | |||
local sing_0 = string.find(str, "_"); | |||
local sing_1 = string.find(str, "|"); | |||
local sing_2 = string.find(str, ","); | |||
if sing_0 and sing_1 and sing_2 then | |||
run = toNumberArray(",", "|", "_"); | |||
elseif sing_0 and sing_1 then | |||
run = toNumberArray("|", "_"); | |||
elseif sing_0 then | |||
run = toNumberArray("_"); | |||
end | |||
if run then | |||
local array = {}; --newBindableArray(); | |||
local t = run(str); | |||
for i, v in pairs(t) do | |||
array[i] = v; | |||
end | |||
return array; | |||
else | |||
return str; | |||
end | |||
end | |||
-- 把字符串转换成数值数组 | |||
function autoMultiArray2(str) | |||
local run = nil; | |||
local sing_0 = string.find(str, ","); | |||
local sing_1 = string.find(str, ":"); | |||
local sing_2 = string.find(str, "_"); | |||
if sing_0 and sing_1 and sing_2 then | |||
run = toNumberArray(",", ":", "_"); | |||
elseif sing_0 and sing_1 then | |||
run = toNumberArray(",", ":"); | |||
elseif sing_2 then | |||
run = toNumberArray("_"); | |||
end | |||
if run then | |||
local array = {}; --newBindableArray(); | |||
local t = run(str); | |||
for i, v in pairs(t) do | |||
array[i] = v; | |||
end | |||
return array; | |||
else | |||
return str; | |||
end | |||
end | |||
function autoAllMultiArray(str) | |||
local type = string.find(str, ":"); | |||
if type then | |||
return autoMultiArray2(str); | |||
else | |||
return autoMultiArray(str); | |||
end | |||
end | |||
--str是这种格式的 2016-11-1 23:00:00 | |||
function stringToTimeStamp(str) | |||
local data = string.split(str , " "); | |||
local timeInfo = string.split(data[2] , ":"); | |||
local dateInfo = string.split(data[1] , "-"); | |||
local time = {}; | |||
time.year = tonumber(dateInfo[1]); | |||
time.month = tonumber(dateInfo[2]); | |||
time.day = tonumber(dateInfo[3]); | |||
time.hour = tonumber(timeInfo[1]); | |||
time.min = tonumber(timeInfo[2]); | |||
time.sec = tonumber(timeInfo[3]); | |||
return BeijingTime.timeFunc(time); | |||
end | |||
function toNumber(str) | |||
return tonumber(str) or 0 | |||
end | |||
-- 把255,255,255格式的字符串转换成cc.Color | |||
function toColor3B(colorString) | |||
local numberArray = toNumberArray(",")(colorString) | |||
if #numberArray ~= 3 then | |||
return nil | |||
else | |||
local color = ccColor3B(); | |||
color.r = numberArray[1]; | |||
color.g = numberArray[2]; | |||
color.b = numberArray[3]; | |||
return color; | |||
end | |||
end | |||
-- 把多重参数转换成表返回 | |||
local function packMultiArgToTable(...) | |||
return {...} | |||
end | |||
-- 使用lua模式匹配把一个字符串转换成数组 | |||
function toArrayPattern(pattern) | |||
return function(str) | |||
local result = packMultiArgToTable(string.find(str,pattern)); | |||
if result[1] == nil then | |||
error("模式匹配失败:" , pattern); | |||
return; | |||
else | |||
return result; | |||
end | |||
end | |||
end | |||
-- XML翻译器 | |||
TextTranslator = {}; | |||
-- 收集所有可以翻译的文本,返回string正则表达式 | |||
function TextTranslator:collect(sourceString) | |||
print("收集一般文本" , sourceString); | |||
local text = string.trim(sourceString); | |||
local index = 1; | |||
local function getReplace(s) | |||
local ret = "[ctln" .. index .. "]"; | |||
index = index + 1; | |||
return ret; | |||
end | |||
text = string.gsub(text , "[0-9]+" , getReplace); | |||
return text; | |||
end | |||
-- 翻译文本 | |||
-- sourceString 源文本 | |||
-- translated 第三方使用collect翻译后的文本 | |||
-- @return 返回原文翻译后的文本 | |||
function TextTranslator:translate(sourceString , translated) | |||
local index = 1; | |||
local function getReplace(s) | |||
local num = "%[ctln" .. index .. "%]"; | |||
index = index + 1; | |||
translated = string.gsub(translated , num , s); | |||
return s; | |||
end | |||
string.gsub(sourceString , "[0-9]+" , getReplace); | |||
return translated; | |||
end | |||
-- XML翻译器 | |||
XmlTranslator = {}; | |||
-- 收集所有可以翻译的文本,返回string正则表达式 | |||
function XmlTranslator:collect(sourceString) | |||
local function onStartElement(name , atts) | |||
end | |||
local function onEndElement(name , atts) | |||
end | |||
local numIndex = 1; | |||
local tagIndex = 1; | |||
local texts = {}; | |||
local function getNumReplace(s) | |||
local ret = "[ctln" .. numIndex .. "]"; | |||
numIndex = numIndex + 1; | |||
return ret; | |||
end | |||
local function onText(text) | |||
local re = string.trim(text); | |||
if re ~= "" then | |||
re = string.gsub(re , "[0-9]+" , getNumReplace); | |||
table.insert(texts , re); | |||
table.insert(texts , "[ctlt" .. tostring(tagIndex) .. "]"); | |||
tagIndex = tagIndex + 1; | |||
end | |||
end | |||
local success , err = tiny.eval("<font>" .. sourceString .. "</font>" , onStartElement , onEndElement , onText) | |||
if not success then | |||
return TextTranslator:collect(sourceString); | |||
end | |||
if #texts > 1 then | |||
texts[#texts] = nil; | |||
end | |||
return table.concat(texts); | |||
end | |||
-- 翻译文本 | |||
-- sourceString 源文本 | |||
-- translated 第三方使用collect翻译后的文本 | |||
-- @return 返回原文翻译后的文本 | |||
function XmlTranslator:translate(sourceString , translated) | |||
local function onStartElement(name , atts) | |||
end | |||
local function onEndElement(name , atts) | |||
end | |||
local xmlText = "<font>" .. sourceString .. "</font>"; | |||
local lastParseIndex = 1; | |||
local nums = {}; | |||
local tags = {}; | |||
local function onText(text , currentByteIndex) | |||
local re = string.trim(text); | |||
if re ~= "" then | |||
local ltrimLen = #text - #string.ltrim(text); | |||
local function getNumReplace(s) | |||
table.insert(nums , s); | |||
return s; | |||
end | |||
string.gsub(re , "[0-9]+" , getNumReplace); | |||
table.insert(tags , string.sub(xmlText , lastParseIndex , currentByteIndex + ltrimLen)); | |||
lastParseIndex = currentByteIndex + ltrimLen + string.len(re) + 1; | |||
end | |||
end | |||
-- 解析xml | |||
local success , err = tiny.eval(xmlText , onStartElement , onEndElement , onText) | |||
if not success then | |||
return TextTranslator:translate(sourceString , translated); | |||
end | |||
-- 尾字符串 | |||
if lastParseIndex <= #xmlText - string.len("</font>") then | |||
table.insert(tags , string.sub(xmlText , lastParseIndex , #xmlText - string.len("</font>"))); | |||
end | |||
local count = #tags; | |||
-- 替换数字 | |||
for i , v in ipairs(nums) do | |||
local num = "%[ctln" .. tostring(i) .. "%]"; | |||
translated = string.gsub(translated , num , v); | |||
end | |||
-- 替换控制字符串,去头去尾 | |||
for i = 1 , #tags - 2 do | |||
local tag = "%[ctlt" .. tostring(i) .. "%]"; | |||
local v = string.gsub(tags[i + 1] , "%%" , "%%%%"); | |||
translated = string.gsub(translated , tag , v); | |||
end | |||
-- 头 | |||
if #tags > 0 then | |||
translated = string.sub(tags[1] , string.len("<font>") + 1) .. translated; | |||
end | |||
-- 尾 | |||
if #tags > 1 then | |||
translated = translated .. tags[#tags]; | |||
end | |||
return translated; | |||
end |
@@ -0,0 +1,136 @@ | |||
local MAX_COUNT=5 | |||
local TASK_ID=1 | |||
local DownloaderHeadManager = { | |||
downCount=0, | |||
tasks={}, | |||
dowloadTasks={}, | |||
scheduleId=nil, | |||
}--class("DownloaderHeadManager") | |||
function DownloaderHeadManager.addTask(node,imageUrl, fileName, updateHeadImage) | |||
--如果在队列里面 还没开始下载 则更新数据就行 | |||
local isExist,oldTask=DownloaderHeadManager.isExitTask(node) | |||
if isExist then | |||
oldTask.imageUrl=imageUrl | |||
oldTask.fileName=fileName | |||
oldTask.updateHeadImage=updateHeadImage | |||
return | |||
end | |||
--如果已经开始下载 | |||
local isDownload,oldTask=DownloaderHeadManager.isExitDowloadTask(node) | |||
if isDownload then | |||
if oldTask.imageUrl==imageUrl then | |||
oldTask.updateHeadImage=updateHeadImage | |||
return | |||
end | |||
end | |||
local task={ | |||
node=node, | |||
imageUrl=imageUrl, | |||
fileName=fileName, | |||
updateHeadImage=updateHeadImage, | |||
id=TASK_ID, | |||
} | |||
dump(task,"DownloaderHeadManager.addTask") | |||
-- logD(" DownloaderHeadManager.addTask",tabletostring(task)) | |||
table.insert(DownloaderHeadManager.tasks,task) | |||
TASK_ID=TASK_ID+1 | |||
DownloaderHeadManager.update() | |||
-- if not DownloaderHeadManager.scheduleId then | |||
-- DownloaderHeadManager.scheduleId=cc.Director:getInstance():getScheduler():scheduleScriptFunc(DownloaderHeadManager.update , 0 , false) | |||
-- end | |||
end | |||
function DownloaderHeadManager.isExitTask(node) | |||
for k,v in pairs(DownloaderHeadManager.tasks) do | |||
if v.node==node then | |||
return true,v | |||
end | |||
end | |||
return false,nil | |||
end | |||
function DownloaderHeadManager.isExitDowloadTask(node) | |||
for k,v in pairs(DownloaderHeadManager.dowloadTasks) do | |||
if v.node==node then | |||
return true,v | |||
end | |||
end | |||
return false,nil | |||
end | |||
function DownloaderHeadManager.removeDownloadTask(task) | |||
for k,v in pairs(DownloaderHeadManager.dowloadTasks) do | |||
if v.id==task.id then | |||
table.remove(DownloaderHeadManager.dowloadTasks,k) | |||
return | |||
end | |||
end | |||
end | |||
function DownloaderHeadManager.update() | |||
logD("DownloaderHeadManager.update11111111111") | |||
if #DownloaderHeadManager.tasks>0 and DownloaderHeadManager.downCount<MAX_COUNT then | |||
print("DownloaderHeadManager.update downCount:"..DownloaderHeadManager.downCount.." total:"..(#DownloaderHeadManager.tasks)) | |||
DownloaderHeadManager.downCount=DownloaderHeadManager.downCount+1 | |||
local task=DownloaderHeadManager.tasks[#DownloaderHeadManager.tasks] | |||
DownloaderHeadManager.tasks[#DownloaderHeadManager.tasks]=nil | |||
if task.node and not tolua.isnull(task.node) then | |||
DownloaderHeadManager.download(task) | |||
else | |||
print("不存在 DownloaderHeadManager.update downCount:"..DownloaderHeadManager.downCount.." total:"..(#DownloaderHeadManager.tasks)) | |||
DownloaderHeadManager.downCount=DownloaderHeadManager.downCount-1 | |||
end | |||
end | |||
logD("DownloaderHeadManager.update2222222222") | |||
-- if #DownloaderHeadManager.tasks ==0 then | |||
-- logD("结束头像更新") | |||
-- cc.Director:getInstance():getScheduler():unscheduleScriptEntry(DownloaderHeadManager.scheduleId) | |||
-- DownloaderHeadManager.scheduleId=nil | |||
-- end | |||
end | |||
function DownloaderHeadManager.download(task) | |||
-- DownloaderHeadManager.dowloadTasks[] | |||
table.insert(DownloaderHeadManager.dowloadTasks,task) | |||
local function callback() | |||
dump(task,"DownloaderHeadManager.download callback downCount:"..DownloaderHeadManager.downCount) | |||
DownloaderHeadManager.downCount=DownloaderHeadManager.downCount-1 | |||
DownloaderHeadManager.update() | |||
if task.updateHeadImage then | |||
task.updateHeadImage() | |||
end | |||
DownloaderHeadManager.removeDownloadTask(task) | |||
end | |||
dowloadImageFile(task.imageUrl,task.fileName,callback) | |||
-- if isWin32Platform() then | |||
-- getImageFromUrlWithTime(task.imageUrl, task.fileName, nil, callback) | |||
-- else | |||
-- local fullPath = cc.FileUtils:getInstance():getWritablePath()..task.fileName | |||
-- local function onFinish(result) | |||
-- local resultJson = json.decode(result) | |||
-- dump(resultJson,"DownloaderHeadManager.download onFinish") | |||
-- local code = tonumber(resultJson.code) | |||
-- local msg = resultJson.message | |||
-- callback() | |||
-- local isExist = cc.FileSystem:fileExists(fullPath) | |||
-- if isExist then | |||
-- saveImageTime(task.fileName, os.time()) | |||
-- end | |||
-- end | |||
-- app.plugin:createTask(task.imageUrl,fullPath,onFinish,-1) | |||
-- end | |||
end | |||
return DownloaderHeadManager |
@@ -0,0 +1,14 @@ | |||
-- 可以使用一个CE文件作为AI控制的ModelNode | |||
cc.AIModelNode.ClassName = "AIModelNode" | |||
function cc.AIModelNode:loadFromXmlNode(xmlNode) | |||
cc.ModelNode.loadFromXmlNode(self , xmlNode); | |||
self:setAIFile(xmlNode.AIFile); | |||
end | |||
cc.AIModelNode.createNode = cc.AIModelNode.create; | |||
function cc.AIModelNode:setDefaults() | |||
self:setMeshFile("res/default/DefaultModel/DefaultModel.gpb"); | |||
end |
@@ -0,0 +1,294 @@ | |||
-- 动画播放实例,根据状态表来决定什么状态播放什么动画 | |||
-- 对外接口: | |||
--[[ | |||
self.Entity 骨骼动画的节点 | |||
self.StateValues 可以用来做数据绑定的状态值列表 | |||
self.OnStateFinished 状态播放完成的回调,参数形式OnStateFinish(animEntity, key , value) | |||
self.OnGetNextValue 状态播放完成后需要把value设置成什么的回调,,参数形式OnGetNextValue(animEntity, key , value),函数里要返回一个int,表示value要变成什么 | |||
self:setValue | |||
self:getValue | |||
--]] | |||
local AnimEntity = class("AnimEntity") | |||
-- 初始化,传进来initStatus是状态表,拥有多少个状态,以及各个状态的值 | |||
-- animation 动画名字 | |||
-- loop 是否循环播放 | |||
-- staticWhenEnd 是否静止在最后一帧 | |||
-- randomPosition 开始播放这个动画时是否使用随机位置 | |||
--[[ | |||
local status = { | |||
death = | |||
{ | |||
1 = {animation = "death" , loop = true}; | |||
}; | |||
skill = | |||
{ | |||
1 = {animation = "skill" , loop = false}; | |||
}; | |||
attack = | |||
{ | |||
1 = {animation = "attack" , loop = false}; | |||
}; | |||
move = | |||
{ | |||
0 = {animation = "stand" , loop = true}; | |||
1 = {animation = "move" , loop = true}; | |||
}; | |||
} | |||
local function getAnimation(values) | |||
if values.death == 1 then | |||
return status.death[1]; | |||
elseif values.skill == 1 then | |||
return status.skill[1]; | |||
elseif values.attack == 1 then | |||
return status.attack[1]; | |||
elseif values.move == 1 then | |||
return status.move[1]; | |||
else | |||
return status.move[0]; | |||
end | |||
end | |||
local entity = AnimEntity:new(skeleton , status , getAnimation); | |||
--]] | |||
function AnimEntity:ctor(skeletonEntity , initStatus , callbackGetAnimation) | |||
self.Status = initStatus; | |||
self.StateValues = require("luaScript.Protocol.BindableArray")(); | |||
self.CallbackGetAnimation = callbackGetAnimation | |||
self.CurrentAnimation = nil; | |||
self.Entity = skeletonEntity; | |||
skeletonEntity.AnimEntity = self; | |||
self:initStatus(); | |||
end | |||
-- 初始化状态表 | |||
function AnimEntity:initStatus() | |||
for i , v in pairs(self.Status) do | |||
self.StateValues[i] = 0; | |||
-- 初始化所有动画长度 | |||
for ii , state in pairs(v) do | |||
state.OnStateFinished = {}; | |||
state.OnGetNextValue = {}; | |||
local clipFile; | |||
if self.Entity.getClipFile then | |||
clipFile = self.Entity:getClipFile(); | |||
end | |||
if clipFile then | |||
local clip = clipFile:getAnimationClip(state.animation); | |||
if clip == nil then | |||
print("获取模型动画" .. state.animation .. "失败" , self.Entity:getMeshFile()); | |||
else | |||
-- 这个动画的持续时间为毫秒 | |||
state.duration = clip:getDuration() / 1000 / clip:getSpeed(); | |||
if state.duration == nil then | |||
error("获取模型动画" .. state.animation .. "长度失败" , self.Entity:getMeshFile()); | |||
end | |||
-- 这里不用侦听了,因为我们统一通过Action来停止 | |||
-- 侦听动画结束回调 | |||
--self.Entity:getAnimationClip(state.animation):addEndListener(function()self:onPlayEnd(state.animation)end); | |||
end | |||
end | |||
end | |||
end | |||
-- 侦听状态改变通知 | |||
self.Entity:bindUpdate(self.StateValues , handler(self , self.updateState)); | |||
local function initAnimation(index) | |||
if self.CurrentAnimation then | |||
self:onChangeAnimation(nil , self.CurrentAnimation); | |||
end | |||
end | |||
self.Entity:runOnLoad(initAnimation); | |||
end | |||
--[[ | |||
-- 事件回调 | |||
function AnimEntity:onPlayEnd(animation) | |||
-- 动画播放完毕 | |||
-- 完成了一次循环,则把非循环动画停止 | |||
if self.CurrentAnimation ~= nil and animation == self.CurrentAnimation.animation and not self.CurrentAnimation.loop and not self.CurrentAnimation.staticWhenEnd then | |||
--print(tostring(self) .. "动画complete" .. animation); | |||
self.CurrentAnimation = nil; | |||
end | |||
end | |||
--]] | |||
-- 一个状态的动作是否无限长 | |||
function AnimEntity:isInfiniteByState(stateName, stateValue) | |||
local stateInfo = self.Status[stateName] | |||
if stateInfo ~= nil and stateInfo[stateValue] ~= nil then | |||
return stateInfo[stateValue].loop | |||
end | |||
return false | |||
end | |||
-- 改变状态值 | |||
function AnimEntity:setValue(state , value) | |||
self.StateValues[state] = value; | |||
end | |||
-- 获取状态值 | |||
function AnimEntity:getValue(state) | |||
return self.StateValues[state]; | |||
end | |||
function AnimEntity:addStateFinishListener(state , value , listener) | |||
local stateStatus = self.Status[state][value]; | |||
if stateStatus.OnStateFinishedLoop then | |||
print("AnimEntity:addStateFinishListener,添加无效", state, value) | |||
return | |||
end | |||
stateStatus.OnStateFinished[listener] = listener; | |||
end | |||
function AnimEntity:removeStateFinishListener(state , value , listener) | |||
local stateStatus = self.Status[state][value]; | |||
if stateStatus.OnStateFinishedLoop then | |||
--print("AnimEntity:removeStateFinishListener,移除无效, 遍历完成后会全部移除掉的", state, value) | |||
return | |||
end | |||
stateStatus.OnStateFinished[listener] = nil; | |||
end | |||
function AnimEntity:addNextValueListener(state , value , listener) | |||
local stateStatus = self.Status[state][value]; | |||
if stateStatus.OnGetNextValueLoop then | |||
print("AnimEntity:addNextValueListener,添加无效", state, value) | |||
return | |||
end | |||
stateStatus.OnGetNextValue[listener] = listener; | |||
end | |||
function AnimEntity:removeNextValueListener(state , value , listener) | |||
local stateStatus = self.Status[state][value]; | |||
if stateStatus.OnGetNextValueLoop then | |||
print("AnimEntity:removeNextValueListener,移除无效, 遍历完成后会全部移除掉的", state, value) | |||
return | |||
end | |||
stateStatus.OnGetNextValue[listener] = nil; | |||
end | |||
function AnimEntity:resetValues() | |||
for i , v in self.StateValues:pairs() do | |||
if v ~= 0 then | |||
self.StateValues[i] = 0; | |||
end | |||
end | |||
end | |||
-- 更新状态 | |||
function AnimEntity:updateState(entity , key , value) | |||
--print(tostring(self) .. "动画状态改变:" .. key .. " = " .. value); | |||
-- 找不到对应的状态名(则说明设置错了) | |||
if self.Status[key] == nil then | |||
print("找不到对应的状态名:" .. key); | |||
return | |||
end | |||
local state = self.Status[key][value]; | |||
if state then | |||
if tolua.isnull(state.Action) then | |||
-- 非循环状态,则自动停止 | |||
if not state.loop then | |||
local function onEnd() | |||
state.Action = nil; | |||
state.OnStateFinishedLoop = true | |||
-- 动画状态播放完成回调 | |||
for i , v in pairs(state.OnStateFinished) do | |||
v(self, key , value); | |||
end | |||
state.OnStateFinishedLoop = false | |||
state.OnStateFinished = {} | |||
--print(tostring(self) .. "动画状态播放完毕" .. state.animation); | |||
if not state.staticWhenEnd then | |||
local retValue = 0; | |||
state.OnGetNextValueLoop = true | |||
-- 获取播放完毕要设置的值 | |||
for i , v in pairs(state.OnGetNextValue) do | |||
local nextValue = v(self, key , value); | |||
if nextValue then | |||
retValue = nextValue; | |||
end | |||
end | |||
state.OnGetNextValueLoop = false | |||
state.OnGetNextValue = {} | |||
self:setValue(key , retValue); | |||
end | |||
end | |||
-- 当模型没有这个动画时duration在开始的时候并没有赋值 | |||
if state.duration ~= nil then | |||
-- 时间到了之后,自动把状态设置成0 | |||
state.Action = self.Entity:runActions(cc.DelayTime:create(state.duration) , onEnd); | |||
state.Action.OnEnd = onEnd; | |||
else | |||
-- 没有这个动画的立马回调 | |||
onEnd(); | |||
end | |||
end | |||
end | |||
end | |||
local anim = self.CallbackGetAnimation(self.StateValues) | |||
self:setAnimation(anim); | |||
end | |||
-- 设置当前状态 | |||
function AnimEntity:setAnimation(animation) | |||
if self.CurrentAnimation == animation then | |||
return; | |||
end | |||
local from = self.CurrentAnimation; | |||
self.CurrentAnimation = animation; | |||
if self.Entity:getModelScene() then | |||
self:onChangeAnimation(from , animation); | |||
end | |||
end | |||
-- 动画改变通知 | |||
function AnimEntity:onChangeAnimation(from , to) | |||
--print(tostring(self) .. "播放动画" .. to.animation); | |||
local fromClip; | |||
-- 先停止之前的动画 | |||
if from then | |||
fromClip = self.Entity:getAnimationClip(from.animation); | |||
-- 停止回调 | |||
if from.Action then | |||
if not tolua.isnull(from.Action) then | |||
from.Action.OnEnd(); | |||
self.Entity:stopAction(from.Action) | |||
end | |||
from.Action = nil; | |||
end | |||
end | |||
local targetClip = self.Entity:getAnimationClip(to.animation); | |||
if targetClip then | |||
if to.loop then | |||
targetClip:setRepeatCount(0); | |||
else | |||
targetClip:setRepeatCount(1); | |||
end | |||
if fromClip then | |||
--print("从" , fromClip:getId() , "切换到" , targetClip:getId()); | |||
fromClip:crossFade(targetClip , 200); | |||
else | |||
--print("直接播放" , targetClip:getId()); | |||
targetClip:play(); | |||
end | |||
-- 随机设置开始位置 | |||
if to.randomPosition then | |||
targetClip:setTimePosition(math.random(0 , targetClip:getDuration())); | |||
end | |||
end | |||
end | |||
return AnimEntity; |
@@ -0,0 +1,7 @@ | |||
cc.AttachToBoneAction = cc.AttachToBoneEffectAction | |||
cc.AttachToBoneEffectAction.ClassName = "AttachToBoneEffectAction" | |||
function cc.AttachToBoneEffectAction:loadFromXmlNode(xmlNode) | |||
self:setBoneName(xmlNode.BoneName); | |||
end |
@@ -0,0 +1,21 @@ | |||
-- 绑定UI | |||
cc.Billboard2DNode.ClassName = "Billboard2DNode" | |||
function cc.Billboard2DNode:createNode() | |||
local layer = cc.Billboard2DNode:create(); | |||
return layer; | |||
end | |||
function cc.Billboard2DNode:setDefaults() | |||
end | |||
function cc.Billboard2DNode:loadFromXmlNode(xmlNode) | |||
cc.EffectNode.loadFromXmlNode(self , xmlNode) | |||
end | |||
function cc.Billboard2DNode:getSelectBox() | |||
local box = cc.BoundingBox:new(0,0,0,10,10,10); | |||
box:transform(self:getWorldMatrix()); | |||
return box; | |||
end |
@@ -0,0 +1,21 @@ | |||
-- 绑定UI | |||
cc.Billboard3DNode.ClassName = "Billboard3DNode" | |||
function cc.Billboard3DNode:createNode() | |||
local layer = cc.Billboard3DNode:create(); | |||
return layer; | |||
end | |||
function cc.Billboard3DNode:setDefaults() | |||
end | |||
function cc.Billboard3DNode:loadFromXmlNode(xmlNode) | |||
cc.EffectNode.loadFromXmlNode(self , xmlNode) | |||
end | |||
function cc.Billboard3DNode:getSelectBox() | |||
local box = cc.BoundingBox:new(0,0,0,1,1,1); | |||
box:transform(self:getWorldMatrix()); | |||
return box; | |||
end |
@@ -0,0 +1,3 @@ | |||
require("luaScript.Tools.Effect.EffectAction") | |||
require("luaScript.Tools.Effect.RotationAction") | |||
require("luaScript.Tools.Effect.AttachToBoneAction") |
@@ -0,0 +1,24 @@ | |||
require("luaScript.Tools.Effect.CCEffectNode") | |||
-- 链接到其他Effect文件的EffectNode | |||
cc.EffectFileEffectNode = cc.EffectFileNode | |||
cc.EffectFileNode.ClassName = "EffectFileNode" | |||
function cc.EffectFileNode:loadFromXmlNode(xmlNode) | |||
cc.EffectNode.loadFromXmlNode(self , xmlNode); | |||
self:setEffectFile(xmlNode.EffectFile); | |||
end | |||
function cc.EffectFileNode:createNode() | |||
local layer = cc.EffectFileNode:create(); | |||
return layer; | |||
end | |||
function cc.EffectFileNode:setDefaults() | |||
self:setEffectFile("res/default/test.effect"); | |||
end | |||
function cc.EffectFileNode:getSelectBox() | |||
local box = cc.BoundingBox:new(0,0,0,1,1,1); | |||
box:transform(self:getWorldMatrix()); | |||
return box; | |||
end |
@@ -0,0 +1,44 @@ | |||
require("luaScript.Tools.Effect.CCEffectActions") | |||
-- 一个光效基类 | |||
cc.EffectNode.ClassName = "EffectNode" | |||
function cc.EffectNode:createNode() | |||
local layer = cc.EffectNode:create(); | |||
return layer; | |||
end | |||
-- 获得选择框,用来编辑器框选的 | |||
function cc.EffectNode:getSelectBox() | |||
return cc.Node.getSelectBox(self); | |||
end | |||
function cc.EffectNode:loadFromXmlNode(xmlNode) | |||
cc.Node.loadFromXmlNode(self , xmlNode); | |||
if xmlNode.StartTime then | |||
self:setStartTime(xmlNode.StartTime); | |||
end | |||
if xmlNode.TimeToPlay then | |||
self:setTimeToPlay(xmlNode.TimeToPlay); | |||
end | |||
if xmlNode.AutoPlay ~= nil then | |||
self:setAutoPlay(xmlNode.AutoPlay); | |||
end | |||
local actions = xmlNode.Actions; | |||
if actions then | |||
for i , v in ipairs(actions) do | |||
self:addAction(createActionFromXmlNode(v)); | |||
end | |||
end | |||
-- 是否需要自动播放动画剪切 | |||
if xmlNode.AutoPlayCurve == nil then | |||
self:setAutoPlayCurve(true) | |||
else | |||
self:setAutoPlayCurve(xmlNode.AutoPlayCurve); | |||
end | |||
-- 默认是不显示的,通过play来显示 | |||
self:setVisible(false); | |||
end |
@@ -0,0 +1,24 @@ | |||
require("luaScript.Tools.Effect.CCEffectNode") | |||
-- 自定义相机节点 | |||
cc.CustomCameraNode.ClassName = "CustomCameraNode" | |||
function cc.CustomCameraNode:loadFromXmlNode(xmlNode) | |||
cc.EffectNode.loadFromXmlNode(self , xmlNode); | |||
self:setSpherical(xmlNode.Spherical); | |||
self:setOffset(xmlNode.Offset); | |||
self:setFieldOfView(xmlNode.FieldOfView); | |||
self:setNearPlane(xmlNode.NearPlane); | |||
self:setFarPlane(xmlNode.FarPlane); | |||
end | |||
function cc.CustomCameraNode:createNode() | |||
local layer = cc.CustomCameraNode:create(); | |||
return layer; | |||
end | |||
function cc.CustomCameraNode:getSelectBox() | |||
local box = cc.BoundingBox:new(0,0,0,1,1,1); | |||
box:transform(self:getWorldMatrix()); | |||
return box; | |||
end |