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
|