201 lines
6.0 KiB
Lua
201 lines
6.0 KiB
Lua
|
|
-- 组包
|
|||
|
|
require("public.CLLInclude")
|
|||
|
|
require("bio.BioUtl")
|
|||
|
|
require("toolkit.CLLPrintEx")
|
|||
|
|
require("toolkit.BitUtl")
|
|||
|
|
|
|||
|
|
---@class CLLNetSerialize
|
|||
|
|
local CLLNetSerialize = {}
|
|||
|
|
|
|||
|
|
local strLen = string.len
|
|||
|
|
local strSub = string.sub
|
|||
|
|
local strPack = string.pack
|
|||
|
|
local strbyte = string.byte
|
|||
|
|
local strchar = string.char
|
|||
|
|
local insert = table.insert
|
|||
|
|
local concat = table.concat
|
|||
|
|
local maxPackSize = 64 * 1024 - 1
|
|||
|
|
local subPackSize = 64 * 1024 - 1 - 50
|
|||
|
|
local __maxLen = 1024 * 1024
|
|||
|
|
|
|||
|
|
local currPack = {} --处理分包用
|
|||
|
|
local netCfg = {} --配置数据
|
|||
|
|
local index = 0
|
|||
|
|
--============================================================
|
|||
|
|
local EncryptType = {
|
|||
|
|
clientEncrypt = 1,
|
|||
|
|
serverEncrypt = 2,
|
|||
|
|
both = 3,
|
|||
|
|
none = 0,
|
|||
|
|
}
|
|||
|
|
function CLLNetSerialize.setCfg(cfg)
|
|||
|
|
--[[
|
|||
|
|
cfg.encryptType:加密类别,1:只加密客户端,2:只加密服务器,3:前后端都加密,0及其它情况:不加密
|
|||
|
|
cfg.secretKey:密钥
|
|||
|
|
cfg.checkTimeStamp:检测时间戳
|
|||
|
|
cfg.systime:系统时间 long"
|
|||
|
|
]]
|
|||
|
|
netCfg = cfg
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
---@public 添加时间戳
|
|||
|
|
function CLLNetSerialize.addTimestamp(bytes)
|
|||
|
|
if bytes == nil then
|
|||
|
|
return nil
|
|||
|
|
end
|
|||
|
|
index = index + 1
|
|||
|
|
if index > 100 then
|
|||
|
|
index = 0
|
|||
|
|
end
|
|||
|
|
local ts = DateEx.nowMS + index
|
|||
|
|
return BioUtl.number2bio(ts) .. bytes
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
---@public 安全加固
|
|||
|
|
local securityReinforce = function(bytes)
|
|||
|
|
if netCfg.checkTimeStamp then
|
|||
|
|
bytes = CLLNetSerialize.addTimestamp(bytes)
|
|||
|
|
end
|
|||
|
|
local enType = bio2Int(netCfg.encryptType)
|
|||
|
|
if enType == EncryptType.clientEncrypt or enType == EncryptType.both then
|
|||
|
|
bytes = CLLNetSerialize.encrypt(bytes, netCfg.secretKey)
|
|||
|
|
end
|
|||
|
|
return bytes
|
|||
|
|
end
|
|||
|
|
--============================================================
|
|||
|
|
function CLLNetSerialize.packMsg(data, tcp)
|
|||
|
|
local bytes = BioUtl.writeObject(data)
|
|||
|
|
if bytes == nil or tcp == nil or tcp.socket == nil then
|
|||
|
|
return nil
|
|||
|
|
end
|
|||
|
|
local len = strLen(bytes)
|
|||
|
|
if len > maxPackSize then
|
|||
|
|
-- 处理分包
|
|||
|
|
--local packList = ArrayList()
|
|||
|
|
local subPackgeCount = math.floor(len / subPackSize)
|
|||
|
|
local left = len % subPackSize
|
|||
|
|
local count = subPackgeCount
|
|||
|
|
if left > 0 then
|
|||
|
|
count = subPackgeCount + 1
|
|||
|
|
end
|
|||
|
|
for i = 1, subPackgeCount do
|
|||
|
|
local subPackg = {}
|
|||
|
|
subPackg.__isSubPack = true
|
|||
|
|
subPackg.count = count
|
|||
|
|
subPackg.i = i
|
|||
|
|
subPackg.content = strSub(bytes, ((i - 1) * subPackSize) + 1, i * subPackSize)
|
|||
|
|
local _bytes = securityReinforce(BioUtl.writeObject(subPackg))
|
|||
|
|
local package = strPack(">s2", _bytes)
|
|||
|
|
tcp.socket:SendAsync(package)
|
|||
|
|
end
|
|||
|
|
if left > 0 then
|
|||
|
|
local subPackg = {}
|
|||
|
|
subPackg.__isSubPack = true
|
|||
|
|
subPackg.count = count
|
|||
|
|
subPackg.i = count
|
|||
|
|
subPackg.content = strSub(bytes, len - left + 1, len)
|
|||
|
|
local _bytes = securityReinforce(BioUtl.writeObject(subPackg))
|
|||
|
|
local package = strPack(">s2", _bytes)
|
|||
|
|
tcp.socket:SendAsync(package)
|
|||
|
|
end
|
|||
|
|
else
|
|||
|
|
local _bytes = securityReinforce(bytes)
|
|||
|
|
local package = strPack(">s2", _bytes)
|
|||
|
|
tcp.socket:SendAsync(package)
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--============================================================
|
|||
|
|
-- 完整的接口都是table,当有分包的时候会收到list。list[1]=共有几个分包,list[2]=第几个分包,list[3]= 内容
|
|||
|
|
local function isSubPackage(m)
|
|||
|
|
if m.__isSubPack then
|
|||
|
|
--判断有没有cmd
|
|||
|
|
return true
|
|||
|
|
end
|
|||
|
|
return false
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
local function unPackSubMsg(m)
|
|||
|
|
-- 是分包
|
|||
|
|
local count = m.count
|
|||
|
|
local index = m.i
|
|||
|
|
if m.content == nil then
|
|||
|
|
printe("the m.content is nil")
|
|||
|
|
return
|
|||
|
|
end
|
|||
|
|
currPack[index] = m.content
|
|||
|
|
if (#currPack == count) then
|
|||
|
|
-- 说明分包已经取完整
|
|||
|
|
local map = BioUtl.readObject(table.concat(currPack, ""))
|
|||
|
|
currPack = {}
|
|||
|
|
return map
|
|||
|
|
end
|
|||
|
|
return nil
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--============================================================
|
|||
|
|
---@public 解包
|
|||
|
|
function CLLNetSerialize.unpackMsg(buffer, tcp)
|
|||
|
|
local ret = nil
|
|||
|
|
local oldPos = buffer.Position
|
|||
|
|
buffer.Position = 0
|
|||
|
|
local totalLen = buffer.Length
|
|||
|
|
local needLen = buffer:ReadByte() * 256 + buffer:ReadByte()
|
|||
|
|
if (needLen <= 0 and needLen > __maxLen) then
|
|||
|
|
--// 网络Number据错误。断isOpen网络
|
|||
|
|
tcp.socket:close()
|
|||
|
|
return nil
|
|||
|
|
end
|
|||
|
|
local usedLen = buffer.Position
|
|||
|
|
if (usedLen + needLen <= totalLen) then
|
|||
|
|
local lessBuff = Utl.read4MemoryStream(buffer, 0, needLen)
|
|||
|
|
local enType = bio2Int(netCfg.encryptType)
|
|||
|
|
if enType == EncryptType.serverEncrypt or enType == EncryptType.both then
|
|||
|
|
lessBuff = CLLNetSerialize.decrypt(lessBuff, netCfg.secretKey)
|
|||
|
|
end
|
|||
|
|
ret = BioUtl.readObject(lessBuff)
|
|||
|
|
else
|
|||
|
|
--说明长度不够
|
|||
|
|
buffer.Position = oldPos
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
if ret and isSubPackage(ret) then
|
|||
|
|
return unPackSubMsg(ret)
|
|||
|
|
else
|
|||
|
|
return ret
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
--============================================================
|
|||
|
|
local secretKey = ""
|
|||
|
|
---@public 加密
|
|||
|
|
function CLLNetSerialize.encrypt(bytes, key)
|
|||
|
|
return CLLNetSerialize.xor(bytes, key)
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
---@public 解密
|
|||
|
|
function CLLNetSerialize.decrypt(bytes, key)
|
|||
|
|
return CLLNetSerialize.xor(bytes, key)
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
function CLLNetSerialize.xor(bytes, key)
|
|||
|
|
key = key or secretKey
|
|||
|
|
if key == nil or key == "" then
|
|||
|
|
return bytes
|
|||
|
|
end
|
|||
|
|
local len = #bytes
|
|||
|
|
local keyLen = #key
|
|||
|
|
local byte, byte2
|
|||
|
|
local keyIdx = 0
|
|||
|
|
local result = {}
|
|||
|
|
for i = 1, len do
|
|||
|
|
byte = strbyte(bytes, i)
|
|||
|
|
keyIdx = i % keyLen + 1
|
|||
|
|
byte2 = BitUtl.xorOp(byte, strbyte(key, keyIdx))
|
|||
|
|
insert(result, strchar(byte2))
|
|||
|
|
end
|
|||
|
|
return concat(result)
|
|||
|
|
end
|
|||
|
|
--------------------------------------------
|
|||
|
|
return CLLNetSerialize
|