local skynet = require "skynet" local oo = require "Class" local log = require "Log" local crypt = require "skynet.crypt" local redisKeyUrl = require "RedisKeyUrl" local Common = oo.class() local pb = require "pb" Common.word ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" Common.wordNoIAndL ="abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNOPQRSTUVWXYZ" Common.number = "0123456789" Common.numberExceptZero = "123456789" Common.web = "192.168.50.215:8080" Common.redeemUrl = "/web/api/redeemCode/use" Common.getMailUrl = "/web/api/mail/getMail" Common.useMailUrl = "/web/api/mail/useMail" Common.findMailUrl = "/web/api/mail/findMailByMailId" --新增根据mailId查询对应邮件接口 Common.getAnnouncementUrl = "/web/api/announcement/getAnnouncement" Common.addAnnouncementUrl = "/web/api/announcement/gameServerAddAnnouncement" Common.addQuestionnaireUrl = "/web/api/questionnaire/add" --Common.specialChar = "`!@#$%^&*()_+~-=;'?\\/." --特殊字符 --夏鸣星\\(≧▽ Common.specialChar = {} table.insert( Common.specialChar, "`" ) table.insert( Common.specialChar, "!" ) table.insert( Common.specialChar, "@" ) table.insert( Common.specialChar, "#" ) table.insert( Common.specialChar, "$" ) table.insert( Common.specialChar, "%" ) table.insert( Common.specialChar, "^" ) table.insert( Common.specialChar, "&" ) table.insert( Common.specialChar, "*" ) table.insert( Common.specialChar, "(" ) table.insert( Common.specialChar, ")" ) table.insert( Common.specialChar, "_" ) table.insert( Common.specialChar, "+" ) table.insert( Common.specialChar, "~" ) table.insert( Common.specialChar, "-" ) table.insert( Common.specialChar, "=" ) table.insert( Common.specialChar, ";" ) table.insert( Common.specialChar, "'" ) table.insert( Common.specialChar, "\\" ) table.insert( Common.specialChar, "/" ) table.insert( Common.specialChar, "." ) table.insert( Common.specialChar, "'" ) --打印表 function Common:TableToString(t) local sp = " "; local list = {}; local function addline(str) table.insert(list, str); end local function do_tostring(tt, l, ln) local tp = type(tt); if (tp == "table") then l = l + 1; if (l - 1 == 0) then addline("{"); end for k, v in pairs(tt) do local pp = type(v); if (pp == "table") then addline(string.format("%"..l.."s[%s]={",sp,k)); do_tostring(v, l + 1); addline(string.format("%"..l.."s},",sp)); else addline(string.format("%"..l.."s[%s]=%s,",sp,k,tostring(v))); end end if (l - 1 == 0) then addline("}"); end else addline(string.format("%"..l.."s=%s,",sp,k,tostring(tt))); end end do_tostring(t, 0); return table.concat(list, "\n"); end function Common:Split(input, delimiter) input = tostring(input) delimiter = tostring(delimiter) if (delimiter=='') then return false end local pos,arr = 0, {} for st,sp in function() return string.find(input, delimiter, pos, true) end do table.insert(arr, string.sub(input, pos, st - 1)) pos = sp + 1 end table.insert(arr, string.sub(input, pos)) return arr end --是否为同一天 function Common:IsSameDay(time1 , time2) if os.date("*t", time1).year == os.date("*t", time2).year and os.date("*t", time1).month == os.date("*t", time2).month and os.date("*t", time1).day == os.date("*t", time2).day then return true end return false end --是否为连续的一天 function Common:IsSeriesDay(time1 , time2) local t1 = os.date("*t",time1) local t2 = os.date("*t",time2) if t1.yday == t2.yday + 1 then return true elseif t2.yday == t1.yday + 1 then return true end return false end --随机数字ID function Common:RandNumberID( maxCount ) local rand = 0 local name = "" for i = 1, maxCount do local temp = nil if 1 == i then rand = math.random(1,#self.numberExceptZero) temp = string.sub(self.numberExceptZero,rand,rand) name = name .. temp else rand = math.random(1,#self.number) temp = string.sub(self.number,rand,rand) name = name .. temp end end return name end --随机ID function Common:RandID( maxCount ) local rand = 0 local name = "" for i = 1, maxCount do rand = math.random(1,52) local temp = string.sub(self.word,rand,rand) name = name .. temp end return name end --随机ID没有I和L function Common:RandIDNoIAndL( maxCount ) local rand = 0 local name = "" for i = 1, maxCount do rand = math.random(1,48) local temp = string.sub(self.wordNoIAndL,rand,rand) name = name .. temp end return name end --随机name function Common:RandName() local rand = 0 local name = "" for i = 1, 10 do rand = math.random(1,52) local temp = string.sub(self.word,rand,rand) name = name .. temp end return name end --随机token function Common:RandToken() local rand = 0 local token = "" for i = 1, 8 do rand = math.random(1,52) local temp = string.sub(self.word,rand,rand) token = token .. temp end --token = "1234567890" return token end --随机兑换码 function Common:RandRedeemCode() local rand = 0 local name = "" for i = 1, 20 do rand = math.random(1,52) local temp = string.sub(self.word,rand,rand) name = name .. temp end return name end --获取主服ID function Common:GetMainServerID(serverId) local mainServerId = nil mainServerId = string.sub(serverId,1,1) if 0 == #mainServerId then mainServerId = nil end return mainServerId end --获取主服ID function Common:GetClusterConfig(serverId) serverId = tonumber(serverId) for k, v in pairs(skynet.server.gameConfig.ClusterServerConfig) do if serverId == v.serverId then return v end end return nil end function Common:Utf8FormString(t) local bytearr = {} for _, v in ipairs(t) do local utf8byte = v < 0 and (0xff + v + 1) or v table.insert(bytearr, string.char(utf8byte)) end return table.concat(bytearr) end --解析参数 function Common:ParseUrlParam( url ) local newUrl = nil local param = nil local post = string.find(url,"?") newUrl = string.sub(url,1, post -1) param = string.sub(url,post + 1, #url) return newUrl,param end --是否为URL编码 function Common:IsUrlEncode(s) if string.find(s, "%%") then return true else return false end end --URL编码 function Common:UrlEncode(s) s = string.gsub(s, "([^%w%.%- ])", function(c) return string.format("%%%02X", string.byte(c)) end) return string.gsub(s, " ", "+") end --URL解码 function Common:UrlDecode(s) s = string.gsub(s, '%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end) return s end --获取字符串时间 2022-02-22 22:22:22 function Common:GetStrTime( time ) return os.date("%Y-%m-%d %H:%M:%S",time) end --获取字符串日期 2022-02-22 function Common:GetStrDate( time ) return os.date("%Y-%m-%d",time) end --将字符串时间 2022-02-22 22:22:22 转为时间戳 function Common:GetTime( date ) local _, _, y, m, d, _hour, _min, _sec = string.find(date, "(%d+)-(%d+)-(%d+)%s*(%d+):(%d+):(%d+)"); return os.time({year=y, month = m, day = d, hour = _hour, min = _min, sec = _sec}); end --获取一年几月有多少天 function Common:GetDayCount( year , month ) local temp ={31,28,31,30,31,30,31,31,30,31,30,31} --判断是否是闰年,如果为闰年,改变2月是29,否则改变2月是28 if (( year%4==0 and year%100 ~= 0 ) or year%400==0 ) then temp[2] = 29 else temp[2] = 28 end return temp[ month ]; end --获取表结构时间 function Common:GetTableTime() local now = skynet.GetTime() local curr_time = {} curr_time.year = tonumber(os.date("%Y", now)) curr_time.month = tonumber(os.date("%m", now)) curr_time.day = tonumber(os.date("%d", now)) curr_time.hour = tonumber(os.date("%H", now)) curr_time.min = tonumber(os.date("%M", now)) curr_time.sec = tonumber(os.date("%S", now)) return curr_time end --获取之前的某一天的起始和结束时间戳 function Common:GetPreSomeDay( count ) local now = skynet.GetTime() local curr_time = {} curr_time.year = os.date("%Y", now) curr_time.month = os.date("%m", now) curr_time.day = os.date("%d", now) local startTime = os.time({year=curr_time.year, month=curr_time.month, day=curr_time.day - count, hour=0,min=0,sec=0}) local endTime = os.time({year=curr_time.year, month=curr_time.month, day=curr_time.day - count, hour=23,min=59,sec=59}) --startTime = os.date("%Y-%m-%d %H:%M:%S",startTime) --endTime = os.date("%Y-%m-%d %H:%M:%S",endTime) return startTime,endTime end --获取之后的某一天的起始和结束时间戳 function Common:GetAfterSomeDay( count ) local now = skynet.GetTime() local curr_time = {} curr_time.year = os.date("%Y", now) curr_time.month = os.date("%m", now) curr_time.day = os.date("%d", now) local startTime = os.time({year=curr_time.year, month=curr_time.month, day=curr_time.day + count, hour=0,min=0,sec=0}) return startTime end --获取给定时间的之后某天的起始时间 function Common:GetTimeAfterSomeDay( time , count ) local curr_time = {} curr_time.year = os.date("%Y", time) curr_time.month = os.date("%m", time) curr_time.day = os.date("%d", time) local startTime = os.time({year=curr_time.year, month=curr_time.month, day=curr_time.day + count, hour=0,min=0,sec=0}) --local startTime = os.date("%Y-%m-%d %H:%M:%S",startTime) return startTime end --获取给定时间的之后某天的起始时间并且保留精确时间 function Common:GetTimeAfterSomeDayHMS( time , count ) local curr_time = {} curr_time.year = os.date("%Y", time) curr_time.month = os.date("%m", time) curr_time.day = os.date("%d", time) curr_time.hour = os.date("%H", time) curr_time.min = os.date("%M", time) curr_time.sec = os.date("%S", time) local startTime = os.time({year=curr_time.year, month=curr_time.month, day=curr_time.day + count, hour=curr_time.hour,min=curr_time.min,sec=curr_time.sec}) --local startTime = os.date("%Y-%m-%d %H:%M:%S",startTime) return startTime end --获取之后的某一天的时间戳 function Common:GetAfterSomeDayTime( count , hour , min , sec ) hour = hour or 0 min = min or 0 sec = sec or 0 local now = skynet.GetTime() local curr_time = {} curr_time.year = os.date("%Y", now) curr_time.month = os.date("%m", now) curr_time.day = os.date("%d", now) local startTime = os.time({year=curr_time.year, month=curr_time.month, day=curr_time.day + count, hour= hour ,min= min ,sec= sec}) return startTime end --获取之后的某个小时的时间戳 function Common:GetAfterSomeHour( count ) local now = skynet.GetTime() local curr_time = {} curr_time.year = os.date("%Y", now) curr_time.month = os.date("%m", now) curr_time.day = os.date("%d", now) curr_time.hour = os.date("%H", now) curr_time.min = os.date("%M", now) curr_time.sec = os.date("%S", now) --向下取整 获取应该增加的天数 local day = math.floor(count/24) --获取应该增加的小时 local hour = count - 24*day local time = os.time({year=curr_time.year, month=curr_time.month, day=curr_time.day + day, hour=curr_time.hour+hour ,min=curr_time.min ,sec=curr_time.sec}) --local startTime = os.date("%Y-%m-%d %H:%M:%S",startTime) return time end --获取年月天 function Common:GetYearMonthDay() local now = skynet.GetTime() local curTime = {} curTime.year = os.date("%Y", now) curTime.month = os.date("%m", now) curTime.day = os.date("%d", now) return tonumber( curTime.year ) , tonumber( curTime.month ) , tonumber( curTime.day ) end --获取某一天的前后多少天 count可以为正负 function Common:GetSomeDayTime( modifyTime , count ) local curTime = {} curTime.year = os.date("%Y", modifyTime) curTime.month = os.date("%m", modifyTime) curTime.day = os.date("%d", modifyTime) curTime.hour = os.date("%H", modifyTime) curTime.min = os.date("%M", modifyTime) curTime.sec = os.date("%S", modifyTime) local newTime = os.time({year=curTime.year, month=curTime.month, day=curTime.day + count, hour=curTime.hour,min=curTime.min ,sec=curTime.sec}) return newTime end --首字母小写 function Common:FirstAlphabetToLower(str) return (str:gsub("^%u",string.lower)) end --随机不重复的数据 function Common:RandNoRepeatItem( needCount , allItem ) if not allItem then return {} end local maxCircCount = 0 --最大循环数据 local data = {} local cfgCount = #allItem if 0 == cfgCount then return {} end while true do local index = math.random(1,cfgCount) local id = allItem[ index ] local isExist = false --检查商品列表是否有重复 for k, v in pairs( data ) do if v == id then isExist = true break end end if not isExist then --不存在就插入数据 table.insert( data , id ) --超过就退出 if #data >= needCount then break end end maxCircCount = maxCircCount + 1 if maxCircCount >= 2000 then --防止死循环,计算2000次就强制退出 break end end return data end --随机不重复的配置 function Common:RandNoRepeatItemForCfg( needCount , cfg ) if not cfg then return nil end local maxCircCount = 0 --最大循环数据 local data = {} local cfgCount = #cfg while true do local index = math.random(1,cfgCount) local id = cfg[ index ].id local isExist = false --检查商品列表是否有重复 for k, v in pairs( data ) do if v == id then isExist = true break end end if not isExist then --不存在就插入数据 table.insert( data , id ) --最大6个商品,超过就退出 if #data >= needCount then break end end maxCircCount = maxCircCount + 1 if maxCircCount >= 5000 then --防止死循环,计算5000次就强制退出 break end end return data end --获取两点的距离 function Common:Distance(x1,y1,x2,y2) x1,y1,x2,y2 = string.format("%.2f", x1),string.format("%.2f", y1),string.format("%.2f", x2),string.format("%.2f", y2) --由于精度问题,客户端可能发来0.12345645646e+14的数据,所以这里保留2位就行。 return math.sqrt((y2-y1) * (y2-y1)+(x2-x1) * (x2-x1)) end --转换到染色家具ID function Common:TransferColorFurniture( id ) local curFurniture = skynet.server.gameConfig.Furniture[ id ] if not curFurniture then log.info("获取家具配置错误 ID ",id) else if 2 == #curFurniture.dyeFurTrans and 0 == math.floor( curFurniture.id /1000000 ) then return curFurniture.dyeFurTrans[2] * 100000 + curFurniture.dyeFurTrans[1]; else return id end end end --获取星期几 function Common:GetDayInWeek() local t = os.date("*t", skynet.GetTime()) if 1 == t.wday then return 7 else t.wday = t.wday - 1 return t.wday end end --获取给定时间是星期几 function Common:GetDayInWeekByTime(y,m,d) if m == 1 or m == 2 then m = m + 12 y = y - 1 end local m1,_ = math.modf(3 * (m + 1) / 5) local m2,_ = math.modf(y / 4) local m3,_ = math.modf(y / 100) local m4,_ = math.modf(y / 400) local iWeek = (d + 2 * m + m1 + y + m2 - m3 + m4 ) % 7 local weekTab = { ["0"] = 1, ["1"] = 2, ["2"] = 3, ["3"] = 4, ["4"] = 5, ["5"] = 6, ["6"] = 7, } return weekTab[tostring(iWeek)] end --是否为润年 function Common:IsLeapYear(year) if year % 4 == 0 then if year % 100 ~= 0 or year % 400 == 0 then return true -- 能被4整除并且不能同时被100或者400整除则为闰年 else return false end else return false end end --是否为新的一周 function Common:IsNewWeek(time1) local t1 = os.date("*t",time1) --小时间 local t2 = os.date("*t",skynet.GetTime()) --当前时间 local year1 = t1.year local day1 = t1.yday local wday1 = (t1.wday-1 == 0) and 7 or t1.wday-1 local year2 = t2.year local day2 = t2.yday local wday2 = (t2.wday-1 == 0) and 7 or t2.wday-1 --判断是不是同一年 if(year1 == year2) then --如果t1的星期几大于t2的星期几 则肯定是新的一周 if(wday1 > wday2) then return true else --如果两个时间的天数差大于7 则肯定是新的一周 if(day2 - day1 >= 7) then return true end end else --如果t1的星期几大于t2的星期几 则肯定是新的一周 if(wday1 >= wday2) then return true else --如果 小的时间到当年结束的天数 加上 大的时间到当年开始的天数 大于等于7 则肯定是新的一周 local count = 365 if ((year1%4 == 0 and year1%100 ~= 0) or year1%400 == 0) then count = 366 end if((count - day1 + day2) >= 7 )then return true end end end return false end --是否间隔一周 function Common:IsIntervalWeek( time1 ) local t1 = os.date("*t",time1) local t2 = os.date("*t",skynet.GetTime()) if t1.yday + 7== t2.yday then return true end return false end --奖励类型 str 转为 int function Common:AwardTypeStrToInt( type ) local goodsType = nil if "NumericalValue" == type then goodsType = 0 elseif "Furniture" == type then goodsType = pb.enum("EnumGoodsType" , "Furniture") elseif "Decorate" == type or "Decoration" == type then goodsType = pb.enum("EnumGoodsType" , "Decorate") elseif "Flowerpot" == type then goodsType = pb.enum("EnumGoodsType" , "Flowerpot") elseif "Seed" == type then goodsType = pb.enum("EnumGoodsType" , "Seed") elseif "Plant" == type then goodsType = pb.enum("EnumGoodsType" , "Plant") elseif "Clothes" == type then goodsType = pb.enum("EnumGoodsType" , "Clothes") elseif "PetClothes" == type then goodsType = pb.enum("EnumGoodsType" , "PetClothes") elseif "Fertilizer" == type then goodsType = pb.enum("EnumGoodsType" , "Fertilizer") elseif "Ticket" == type then goodsType = pb.enum("EnumGoodsType" , "Prop") elseif "FishType" == type then goodsType = pb.enum("EnumGoodsType" , "Fish") elseif "CuisineMaterial" == type then goodsType = pb.enum("EnumGoodsType" , "CuisineMaterial") elseif "CuisineMenu" == type then goodsType = pb.enum("EnumGoodsType" , "CuisineMenu") elseif "CoffeeType" == type then goodsType = pb.enum("EnumGoodsType" , "Coffee") elseif "Garden" == type then goodsType = pb.enum("EnumGoodsType" , "Garden") elseif "Reward" == type then goodsType = pb.enum("EnumGoodsType" , "RewardId") elseif "Points" == type then goodsType = pb.enum("EnumGoodsType" , "Points") elseif "Suit" == type then goodsType = pb.enum("EnumGoodsType" , "Suit") elseif "ClothesSuit" == type then goodsType = pb.enum("EnumGoodsType" , "ClothesSuit") end return goodsType end --十六进制转字符串 function Common:HexToStr(hex) --判断输入类型 if (type(hex)~="string") then return nil,"hex2str invalid input type" end --拼接字符串 local index=1 local ret="" for index=1,hex:len() do ret=ret..string.format("%02X",hex:sub(index):byte()) end return ret end --将字符串按格式转为16进制串 function Common:StrToHex(str) --判断输入类型 if (type(str)~="string") then return nil,"str2hex invalid input type" end --滤掉分隔符 str=str:gsub("[%s%p]",""):upper() --检查内容是否合法 if(str:find("[^0-9A-Fa-f]")~=nil) then return nil,"str2hex invalid input content" end --检查字符串长度 if(str:len()%2~=0) then return nil,"str2hex invalid input lenth" end --拼接字符串 local index=1 local ret="" for index=1,str:len(),2 do ret=ret..string.char(tonumber(str:sub(index,index+1),16)) end return ret end --获取当前进程ID function Common:GetProcessID( serverId ) local processIds = {} --获取到的进程ID local fp = io.popen( string.format("ps -ef | grep skynet | grep -v grep | grep config_%d | awk '{print $2}'" , serverId)) for pId in fp:lines() do table.insert( processIds , pId) end return processIds end --是否存在 function Common:IsExist( id , allData ) for k, v in pairs( allData ) do if v == id then return true end end return false end --是否存在 function Common:IsExistForID( id , allData ) for k, v in pairs( allData ) do if id == v.id then return true end end return false end --存在就加 function Common:AddForID( id , allData ) for k, v in pairs( allData ) do if v.id == id then return true end end return false end --复制表 function Common:DeepCopy(tb) if tb == nil then return nil -- 参见注1 end local copy = {} for k, v in pairs(tb) do if type(v) == 'table' then copy[k] = self:DeepCopy(v) else copy[k] = v end end -- local meta = table.deepCopy(getmetatable(tb)) setmetatable(copy, self:DeepCopy(getmetatable(tb))) return copy end --获取当前时间是给的时间的差距多少天 function Common:GetTimeGap( time ) local count = 0 if time then local now = os.date("*t", skynet.GetTime()) local next = os.date("*t", time) if now and next then local num1 = os.time({ year = now.year, month=now.month, day=now.day }) local num2 = os.time({ year = next.year, month=next.month, day=next.day }) if num1 and num2 then count = math.abs(num1 - num2) / (3600*24) end end end return count end --是否为新的一月 function Common:IsNewMonth( time1 ) local t1 = os.date("%m",time1) local t2 = os.date("%m",skynet.GetTime()) if t1 ~= t2 then return true end return false end --通过数字分割字符串 function Common:SplitByNumber( input ) local result = {} string.gsub(input , '[^'.. 0123456789 ..']+' , function(value) table.insert(result , value) end) return result end --DES加密 function Common:DesEncode( key, text ) local c = crypt.desencode(key, text, crypt.padding[ "pkcs7" ]) return crypt.base64encode(c) end --DES解密 function Common:DesDecode( key, text ) text = crypt.base64decode(text) return crypt.desdecode(key, text, crypt.padding[ "pkcs7" ]) end --读取二进制文件 function Common:ReadBinaryFileData( filePath ) local file = io.open(filePath, "rb") if not file then return nil end local content = file:read "*all" -- *all reads the whole file file:close() return content end --写入二进制文件 function Common:WriteBinaryFileData( filePath ,data ) os.execute("touch "..filePath) local file = io.open( filePath, "wb") if not file then return nil end file:write(data) file:close() end --是否存在特殊字符 function Common:IsExistSpecialChar( text ) if string.find(text, "'") or string.find(text, "\\") or string.find(text, "\n") or string.find(text, "\t") or string.find(text, "\r") or string.find(text, "\v") or string.find(text, "\b") or string.find(text, "?") or string.find(text, "\0") or string.find(text, "\a") or string.find(text, "\f") then return true else return false end --[[ for k, v in pairs( self.specialChar ) do log.info("11111111111",text,v) if string.find(text, v) then return true end end return false ]] end --是否存在文件夹 function Common:IsExistFolder( folderPath ) local folderExists = false local dir, err = io.open(folderPath, "r") if dir then dir:close() folderExists = true end return folderExists end --是否为屏蔽词 function Common:IsMaskWords( mask ) local pos1,pos2 = nil,nil for k, v in pairs( skynet.server.gameConfig.MaskWords ) do pos1,pos2 = string.find( mask , v ) if pos1 and pos2 and pos1 ~= pos2 and "" ~= v then return true end end return false end --打包数据 function Common:PackData( packBeforeData ) --[[ packBeforeData 的数据格式如下 packBeforeData = {} packBeforeData["key1"] = "value1" packBeforeData["key2"] = "value2" ]] local packAfterData = {} local packIndex = 1 for k, v in pairs( packBeforeData ) do packAfterData[ packIndex ] = k packIndex = packIndex + 1 packAfterData[ packIndex ] = v packIndex = packIndex + 1 end return packAfterData end skynet.server.common = Common return Common