local Debug = CS.UnityEngine.Debug
Object = CS.UnityEngine.Object
Sprite = CS.UnityEngine.Sprite
Texture = CS.UnityEngine.Texture
Color = CS.UnityEngine.Color
ColorUtility = CS.UnityEngine.ColorUtility
Transform = CS.UnityEngine.Transform
RectTransform = CS.UnityEngine.RectTransform
GameObject = CS.UnityEngine.GameObject
Vector2 = CS.UnityEngine.Vector2
Vector3 = CS.UnityEngine.Vector3
Quaternion = CS.UnityEngine.Quaternion
NovaAPI = CS.NovaAPI
CSTimerManager = CS.TimerManager
DOTween = CS.DG.Tweening.DOTween
Sequence = CS.DG.Tweening.DOTween.Sequence
Ease = CS.DG.Tweening.Ease
RotateMode = CS.DG.Tweening.RotateMode
TweenExtensions = CS.TweenExtensions
GameUIUtils = CS.GameUIUtils
local PB = require("pb")
require("functions")
local rapidjson = require("rapidjson")
GameEnum = require("Game.CodeGen.GAME_ENUM_DEFINE")
AllEnum = require("GameCore.Common.AllEnum")
Settings = require("GameCore.Common.Settings")
EventId = require("GameCore.Event.EventId")
EventManager = require("GameCore.Event.EventManager")
PlayerData = require("GameCore.Data.PlayerData")
NetMsgId = require("GameCore.Network.NetMsgId")
HttpNetHandler = require("GameCore.Network.HttpNetHandler")
PanelId = require("GameCore.UI.PanelId")
PanelManager = require("GameCore.UI.PanelManager")
BasePanel = require("GameCore.UI.BasePanel")
BaseCtrl = require("GameCore.UI.BaseCtrl")
RedDotDefine = require("GameCore.RedDot.RedDotDefine")
RedDotManager = require("GameCore.RedDot.RedDotManager")
PopUpManager = require("GameCore.Data.PopUpManager")
local util = require("xlua.util")
async_to_sync = util.async_to_sync
coroutine_call = util.coroutine_call
cs_generator = util.cs_generator
loadpackage = util.loadpackage
auto_id_map = util.auto_id_map
hotfix_ex = util.hotfix_ex
bind = util.bind
createdelegate = util.createdelegate
state = util.state
print_func_ref_by_csharp = util.print_func_ref_by_csharp
cs_coroutine = require("xlua.cs_coroutine")
local serpent = require("serpent")
function printLog(str)
Debug.Log(str)
end
function printWarn(str)
Debug.LogWarning(str)
end
function printError(str)
Debug.LogError(str)
end
function printTable(tb)
if type(tb) == "table" then
print(serpent.block(tb))
end
end
function traceback(str)
Debug.LogError(debug.traceback(str))
end
function timeFormat_MS(value)
local min = math.floor(value / 60)
local sec = value - min * 60
if min < 10 then
min = "0" .. min
end
if sec < 10 then
sec = "0" .. sec
end
return min .. ":" .. sec
end
function timeFormat_HMS(value)
local hor = math.floor(value / 60 / 60)
local min = math.floor((value - hor * 60 * 60) / 60)
local sec = value - hor * 60 * 60 - min * 60
if hor < 10 then
hor = "0" .. hor
end
if min < 10 then
min = "0" .. min
end
if sec < 10 then
sec = "0" .. sec
end
return hor .. ":" .. min .. ":" .. sec
end
function timeFormat_DHMS(value)
local day = math.floor(value / 60 / 60 / 24)
value = value % 86400
local hor = math.floor(value / 60 / 60)
local min = math.floor((value - hor * 60 * 60) / 60)
local sec = value - hor * 60 * 60 - min * 60
if hor < 10 then
hor = "0" .. hor
end
if min < 10 then
min = "0" .. min
end
if sec < 10 then
sec = "0" .. sec
end
if 0 < day then
return string.format("%dd %s", day, hor .. ":" .. min .. ":" .. sec)
else
return hor .. ":" .. min .. ":" .. sec
end
end
function timeFormat_Table(value)
local tbTime = {}
local day = math.floor(value / 60 / 60 / 24)
value = value % 86400
local hour = math.floor(value / 60 / 60)
local min = math.floor((value - hour * 60 * 60) / 60)
local sec = value - hour * 60 * 60 - min * 60
tbTime.day = day
tbTime.hour = hour
tbTime.min = min
tbTime.sec = sec
return tbTime
end
function GetNextWeekRefreshTime()
local nCurTimeWithTimeZone = CS.ClientManager.Instance.serverTimeStampWithTimeZone
local nCurTime = CS.ClientManager.Instance.serverTimeStamp
local tbCurDate = os.date("!*t", nCurTimeWithTimeZone)
local nCurWeekday = tbCurDate.wday
nCurWeekday = nCurWeekday == 1 and 7 or nCurWeekday - 1
local nDays = 7 - nCurWeekday
local nDailyRefreshOffsetHour = ConfigTable.GetConfigNumber("DailyRefreshOffsetHour")
if nDailyRefreshOffsetHour > tbCurDate.hour then
if nCurWeekday == 1 then
nDays = 0
else
nDays = nDays + 1
end
end
local nNextOpenTime = CS.ClientManager.Instance:GetNextRefreshTime(nCurTime)
if 0 < nDays then
for i = 1, nDays do
nCurTime = nNextOpenTime
nNextOpenTime = CS.ClientManager.Instance:GetNextRefreshTime(nCurTime)
end
end
return nNextOpenTime
end
function FormatNum(num)
if num <= 0 then
return 0
else
local t1, t2 = math.modf(num)
if 0 < t2 then
return num
else
return t1
end
end
end
function FormatEffectValue(nValue, bPercent, nFormat)
if bPercent then
nValue = nValue * 100
end
if nValue == 0 and bPercent then
return "0%"
end
local sValue
if nFormat == GameEnum.ValueFormat.Int then
nValue = math.floor(nValue)
sValue = string.format("%d", nValue)
elseif nFormat == GameEnum.ValueFormat.ODP then
sValue = string.format("%.1f", nValue)
sValue = sValue:gsub("0+$", "")
elseif nFormat == GameEnum.ValueFormat.TDP then
sValue = string.format("%.2f", nValue)
sValue = sValue:gsub("0+$", "")
end
sValue = sValue:gsub("%.$", "")
if bPercent then
sValue = sValue .. "%"
end
return sValue
end
function FormatWithCommas(nValue)
local s, integer, decimal = tostring(nValue), "", ""
local dot = string.find(s, "%.")
if dot then
integer = string.sub(s, 1, dot - 1)
decimal = string.sub(s, dot + 1)
else
integer = s
end
integer = string.reverse(integer)
integer = string.gsub(integer, "(%d%d%d)", "%1,")
integer = string.reverse(integer)
if string.sub(integer, 1, 1) == "," then
integer = string.sub(integer, 2)
end
if decimal ~= "" then
return integer .. "." .. decimal
else
return integer
end
end
function indexOfPose(sPose)
local tbCharPose = {
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
"x",
"y",
"z",
"aa",
"ab",
"ac",
"ad",
"ae",
"af",
"ag",
"ah",
"ai",
"aj",
"ak",
"al",
"am",
"an",
"ao",
"ap",
"aq",
"ar",
"as",
"at",
"au",
"av",
"aw",
"ax",
"ay",
"az"
}
local nIdx = table.indexof(tbCharPose, sPose)
if nIdx < 0 then
nIdx = 0
end
return nIdx
end
function instantiate(...)
return GameObject.Instantiate(...)
end
function destroy(obj)
if not obj:IsNull() then
GameObject.Destroy(obj)
end
end
function destroyImmediate(obj)
if not obj:IsNull() then
GameObject.DestroyImmediate(obj)
end
end
function luaCoroutineStart(runner, ...)
return runner:StartCoroutine(util.cs_generator(...))
end
function luaCoroutineStop(runner, coroutine)
runner:StopCoroutine(coroutine)
end
function delChildren(go)
if go.transform.childCount > 0 then
for i = go.transform.childCount, 1, -1 do
local obj = go.transform:GetChild(i - 1).gameObject
destroy(obj)
end
end
end
function ProcContentWord(sContentWord, bUsePresetColor)
if bUsePresetColor == nil then
bUsePresetColor = false
end
local tbContent = string.split(sContentWord, "$")
local sRetContent = tbContent[1]
for i, v in ipairs(tbContent) do
if 1 < i then
local sHeadFourChar = string.sub(v, 1, 4)
local nWordId = tonumber(sHeadFourChar)
local sWord
if type(nWordId) == "number" then
local data = ConfigTable.GetData("ContentWord", nWordId)
if data ~= nil then
sWord = data.Word
end
end
if sWord == nil then
sWord = "$" .. v
else
if bUsePresetColor == true then
local sColor = ConfigTable.GetData("ContentWord", nWordId).PresetColor or ""
if sColor ~= "" then
sWord = string.format("%s", sColor, sWord)
end
end
sWord = string.gsub(v, sHeadFourChar, sWord)
end
sRetContent = sRetContent .. sWord
end
end
return sRetContent
end
function GetLanguageIndex(sLan)
for i, v in ipairs(AllEnum.LanguageInfo) do
if v[1] == sLan then
return i
end
end
return 1
end
function GetLanguageByIndex(nIndex)
local tbLanInfo = AllEnum.LanguageInfo[nIndex]
if tbLanInfo ~= nil then
return tbLanInfo[1]
else
return AllEnum.Language.CN
end
end
function GetLanguageSurfixByIndex(nIndex)
local tbLanInfo = AllEnum.LanguageInfo[nIndex]
if tbLanInfo ~= nil then
return tbLanInfo[3]
else
return "_cn"
end
end
function GetAvgLuaRequireRoot(nIndex)
local sFolderSurfix = GetLanguageSurfixByIndex(nIndex) .. "/"
local sRootPath = "Game/UI/Avg/" .. sFolderSurfix
if AVG_EDITOR == true and NovaAPI.IsRuntimeWindowsPlayer() == true then
sRootPath = "/../../../../" .. sFolderSurfix
end
return sRootPath
end
function ProcAvgTextContent(sContent, nLanguageIndex)
local nIndex = PlayerData.Base:GetPlayerSex() == true and 2 or 1
if nLanguageIndex == nil then
nLanguageIndex = GetLanguageIndex(Settings.sCurrentTxtLanguage)
end
if nLanguageIndex < 1 or nLanguageIndex > #AllEnum.LanguageInfo then
nLanguageIndex = 1
end
sContent = ProcContentWord(sContent, true)
sContent = string.gsub(sContent, "==RT==", "\n")
sContent = string.gsub(sContent, "==PLAYER_NAME==", PlayerData.Base:GetPlayerNickName())
local AvgUIText = require(GetAvgLuaRequireRoot(nLanguageIndex) .. "Preset/AvgUIText")
local mapSex = AvgUIText.SEX
for k, v in pairs(mapSex) do
sContent = string.gsub(sContent, k, v[nIndex])
end
return sContent
end
function ProcAvgTextContentFallback(sTextLan, sVoLan, bIsMale, sCN_F, sCN_M, sJP_F, sJP_M)
if sCN_F == nil then
sCN_F = ""
end
if sCN_M == nil then
sCN_M = ""
end
if sJP_F == nil then
sJP_F = ""
end
if sJP_M == nil then
sJP_M = ""
end
local sContent = ""
local tbFallback
if sTextLan == AllEnum.Language.CN then
tbFallback = {sCN_F}
if bIsMale == true then
table.insert(tbFallback, sCN_M)
end
if sVoLan == AllEnum.Language.JP then
table.insert(tbFallback, sJP_F)
if bIsMale == true then
table.insert(tbFallback, sJP_M)
end
end
elseif sTextLan == AllEnum.Language.JP then
tbFallback = {sJP_F}
if MULTI_LANGUAGE_GENDER_TEXT_COMPATIBLE == true and sJP_F == "" then
table.insert(tbFallback, sCN_F)
end
if bIsMale == true then
table.insert(tbFallback, sJP_M)
if MULTI_LANGUAGE_GENDER_TEXT_COMPATIBLE == true and sJP_M == "" then
table.insert(tbFallback, sCN_M)
end
end
elseif sTextLan == AllEnum.Language.TW or sTextLan == AllEnum.Language.EN or sTextLan == AllEnum.Language.KR then
tbFallback = {sJP_F}
if bIsMale == true then
table.insert(tbFallback, sJP_M)
end
if sVoLan == AllEnum.Language.CN then
table.insert(tbFallback, sCN_F)
if bIsMale == true then
table.insert(tbFallback, sCN_M)
end
end
if MULTI_LANGUAGE_GENDER_TEXT_COMPATIBLE == true and sVoLan == AllEnum.Language.JP and sJP_F == "" and sJP_M == "" then
table.insert(tbFallback, sCN_F)
if bIsMale == true then
table.insert(tbFallback, sCN_M)
end
end
end
if type(tbFallback) == "table" then
local n = #tbFallback
for i = n, 1, -1 do
local s = tbFallback[i]
if type(s) == "string" and s ~= "" then
sContent = s
break
end
end
end
return sContent
end
function AdjustMainRoleAvgCharId(sAvgCharId)
if sAvgCharId == nil then
sAvgCharId = "avg3_100"
end
local tbMainRoleAvgCharId = {"avg3_100", "avg3_101"}
local nIdx = table.indexof(tbMainRoleAvgCharId, sAvgCharId)
if 0 < nIdx then
local nIndex = PlayerData.Base:GetPlayerSex() == true and 2 or 1
return tbMainRoleAvgCharId[nIndex]
else
return sAvgCharId
end
end
function CalcTextAnimDuration(sContent, nLanguageIndex, bIsBB)
local tbInterval = {
0.03,
0.03,
0.03,
0.01,
0.03
}
local tbIntervalForBB = {
0.25,
0.25,
0.25,
0.083,
0.25
}
local nInterval = bIsBB == true and tbIntervalForBB[nLanguageIndex] or tbInterval[nLanguageIndex]
if nInterval == nil then
nInterval = bIsBB == true and tbIntervalForBB[1] or tbInterval[1]
end
local sPureContent = string.gsub(sContent, "<.->", "")
sPureContent = string.gsub(sPureContent, "\n", "")
local nDuration = string.utf8len(sPureContent) * nInterval
return nDuration
end
function Avg_ProcRes_M_F(sName)
local nLen = string.len(sName)
local surfix = string.sub(sName, nLen - 2, nLen)
if surfix == "_MP" or surfix == "_FP" then
if PlayerData.Base:GetPlayerSex() == true then
surfix = "_MP"
else
surfix = "_FP"
end
sName = string.sub(sName, 1, nLen - 3) .. surfix
return sName
else
return sName
end
end
function Avg_ProcEnquotes(s)
s = string.gsub(s, "\\", "")
s = string.gsub(s, "'", "\\'")
s = string.gsub(s, "\"", "\\\"")
return s
end
function Avg_ProcContactsIcon_M_F(sIcon)
local tb = {
"Icon/Head/head_9100_S",
"Icon/Head/head_9101_S"
}
if table.indexof(tb, sIcon) > 0 then
local nIndex = PlayerData.Base:GetPlayerSex() == true and 2 or 1
return tb[nIndex]
else
return sIcon
end
end
function decodeJson(sJson)
local tbData = {}
if type(sJson) == "string" and sJson ~= "" then
tbData = rapidjson.decode(sJson)
if tbData == nil then
tbData = {}
printError("json文本配置格式有误,该文本为:" .. sJson)
end
end
return tbData
end
function IsStartsWith(str, start)
return string.sub(str, 1, string.len(start)) == start
end
function UFT8ToUnicode(convertStr)
if type(convertStr) ~= "string" then
return convertStr
end
local resultDec = 0
local i = 1
local num1 = string.byte(convertStr, i)
if num1 ~= nil then
local tempVar1, tempVar2 = 0, 0
if 0 <= num1 and num1 <= 127 then
tempVar1 = num1
tempVar2 = 0
elseif num1 & 224 == 192 then
local t1 = 0
local t2 = 0
t1 = num1 & 31
i = i + 1
num1 = string.byte(convertStr, i)
t2 = num1 & 63
tempVar1 = t2 | (t1 & 3) << 6
tempVar2 = t1 >> 2
elseif num1 & 240 == 224 then
local t1 = 0
local t2 = 0
local t3 = 0
t1 = num1 & 31
i = i + 1
num1 = string.byte(convertStr, i)
t2 = num1 & 63
i = i + 1
num1 = string.byte(convertStr, i)
t3 = num1 & 63
tempVar1 = (t2 & 3) << 6 | t3
tempVar2 = t1 << 4 | t2 >> 2
end
resultDec = tempVar2 * 256 + tempVar1
end
return resultDec
end
function AddKrParticle(str, nParticleIdx)
local is_korean = function(cp)
return 4352 <= cp and cp <= 4607 or 12592 <= cp and cp <= 12687 or 44032 <= cp and cp <= 55215 or 43360 <= cp and cp <= 43391 or 55216 <= cp and cp <= 55295
end
local is_al = function(cp)
return 65 <= cp and cp <= 90 or 97 <= cp and cp <= 122
end
local start = utf8.offset(str, -1)
local lastChar = string.sub(str, start)
local codePoint = utf8.codepoint(lastChar)
if is_korean(codePoint) then
local modResult = (codePoint - 44032) % 28
if modResult == 0 then
local charTag = AllEnum.KrTags["1"][nParticleIdx]
if charTag ~= nil then
str = str .. charTag
end
else
local charTag = AllEnum.KrTags["2"][nParticleIdx]
if charTag ~= nil then
str = str .. charTag
end
end
elseif is_al(codePoint) then
local charTag = AllEnum.KrTags[1][nParticleIdx]
if charTag ~= nil then
str = str .. charTag
end
end
return str
end
function ParseLanguageParam(sParam)
local param, lang, num = sParam:match("^(.-)_([a-zA-Z]+)(%d+)$")
if not param then
return sParam, nil, nil
end
return param, lang, tonumber(num)
end
function LanguagePost(sLang, nIdx, sStr)
if sLang == "kr" and nIdx ~= nil then
return AddKrParticle(sStr, nIdx)
end
return sStr
end
function RefreshRemainTime(endTime, txtComp)
local curTime = CS.ClientManager.Instance.serverTimeStamp
local remainTime = endTime - curTime
local sTimeStr = ""
if remainTime <= 60 then
local sec = math.floor(remainTime)
sTimeStr = orderedFormat(ConfigTable.GetUIText("Activity_Remain_Time_Sec") or "", sec)
elseif 60 < remainTime and remainTime <= 3600 then
local min = math.floor(remainTime / 60)
local sec = math.floor(remainTime - min * 60)
if sec == 0 then
min = min - 1
sec = 60
end
sTimeStr = orderedFormat(ConfigTable.GetUIText("Activity_Remain_Time_Min") or "", min, sec)
elseif 3600 < remainTime and remainTime <= 86400 then
local hour = math.floor(remainTime / 3600)
local min = math.floor((remainTime - hour * 3600) / 60)
if min == 0 then
hour = hour - 1
min = 60
end
sTimeStr = orderedFormat(ConfigTable.GetUIText("Activity_Remain_Time_Hour") or "", hour, min)
elseif 86400 < remainTime then
local day = math.floor(remainTime / 86400)
local hour = math.floor((remainTime - day * 86400) / 3600)
if hour == 0 then
day = day - 1
hour = 24
end
sTimeStr = orderedFormat(ConfigTable.GetUIText("Activity_Remain_Time_Day") or "", day, hour)
end
NovaAPI.SetTMPText(txtComp, sTimeStr)
return remainTime
end
local DecodeChangeInfo = function(mapChangeInfo)
local mapDecodedChangeInfo = {}
if type(mapChangeInfo) ~= "table" then
return mapDecodedChangeInfo
end
if mapChangeInfo.Props == nil then
return mapDecodedChangeInfo
end
for nIndex, mapGoogleProtobufAny in ipairs(mapChangeInfo.Props) do
if mapGoogleProtobufAny.type_url == "" or mapGoogleProtobufAny.type_url == nil then
printError("ChangeInfo 格式错误")
return mapDecodedChangeInfo
end
local tbSubUrl = string.split(mapGoogleProtobufAny.type_url, "/")
local sProtoMsgName = tbSubUrl[2]
local mapDecodedData = PB.decode(sProtoMsgName, mapGoogleProtobufAny.value)
if mapDecodedChangeInfo[sProtoMsgName] == nil then
mapDecodedChangeInfo[sProtoMsgName] = {}
end
table.insert(mapDecodedChangeInfo[sProtoMsgName], mapDecodedData)
end
return mapDecodedChangeInfo
end
local OpenReceiveByChangeInfo = function(mapChangeInfo, callback, sTip, nTitleType, mapNpc)
local mapReward = PlayerData.Item:ProcessRewardChangeInfo(mapChangeInfo)
UTILS.OpenReceiveByReward(mapReward, callback, sTip, nTitleType, mapNpc)
end
local OpenReceiveByDisplayItem = function(tbItem, mapChangeInfo, callback, sTip, nTitleType, mapNpc)
local mapTrans = PlayerData.Item:ProcessTransChangeInfo(mapChangeInfo)
local tbReward, tbSpReward = PlayerData.Item:ProcessRewardDisplayItem(tbItem, mapTrans)
local mapReward = {
tbReward = tbReward,
tbSpReward = tbSpReward,
tbSrc = mapTrans.tbSrc,
tbDst = mapTrans.tbDst
}
UTILS.OpenReceiveByReward(mapReward, callback, sTip, nTitleType, mapNpc)
end
local OpenReceiveByReward = function(mapReward, callback, sTip, nTitleType, mapNpc)
local bOverflow = PlayerData.State:GetMailOverflow()
local open_mail = function()
if bOverflow then
EventManager.Hit(EventId.OpenMessageBox, {
nType = AllEnum.MessageBox.Alert,
sContent = ConfigTable.GetUIText("Mail_Overflow_Tip"),
callbackConfirm = callback
})
PlayerData.State:SetMailOverflow(false)
elseif callback then
callback()
end
end
local open_trans = function()
local tbSrc, tbDst = {}, {}
local mapOverTrans = PlayerData.Item:GetFragmentsOverflow()
if mapOverTrans and mapOverTrans.tbSrc and #mapOverTrans.tbSrc > 0 then
for _, v in ipairs(mapOverTrans.tbSrc) do
table.insert(tbSrc, v)
end
for _, v in ipairs(mapOverTrans.tbDst) do
table.insert(tbDst, v)
end
end
if mapReward and mapReward.tbSrc and #mapReward.tbSrc > 0 then
for _, v in ipairs(mapReward.tbSrc) do
table.insert(tbSrc, v)
end
for _, v in ipairs(mapReward.tbDst) do
table.insert(tbDst, v)
end
end
if 0 < #tbDst and 0 < #tbSrc then
EventManager.Hit(EventId.OpenPanel, PanelId.ReceiveAutoTrans, tbSrc, tbDst, open_mail)
else
open_mail()
end
end
local open_normal = function()
if mapReward and mapReward.tbReward and #mapReward.tbReward > 0 then
if mapNpc then
EventManager.Hit(EventId.OpenPanel, PanelId.ReceivePropsNPC, mapReward.tbReward, mapNpc, open_trans, nTitleType)
else
EventManager.Hit(EventId.OpenPanel, PanelId.ReceivePropsTips, mapReward.tbReward, open_trans, sTip, nTitleType)
end
else
open_trans()
end
end
if mapReward and mapReward.tbSpReward and #mapReward.tbSpReward > 0 then
EventManager.Hit(EventId.OpenPanel, PanelId.ReceiveSpecialReward, mapReward.tbSpReward, open_normal)
else
open_normal()
end
end
local strLengthConfig = {
{
tbRange = {
{11904, 12255},
{13312, 19903},
{19968, 40959}
},
sType = "中文",
nCount = 2
},
{
tbRange = {
{4352, 4607},
{12592, 12687},
{44032, 55215}
},
sType = "韩文",
nCount = 2
},
{
tbRange = {
{12352, 12543},
{12784, 12799}
},
sType = "日文",
nCount = 2
},
{
tbRange = {
{65280, 65519}
},
sType = "全角符号",
nCount = 2
}
}
local GetParamStrLen = function(sParam)
sParam = string.gsub(sParam, "?[^>]+>", "")
local nLength = 0
local nIndex = 1
while true do
local curByte = string.byte(sParam, nIndex)
local byteCount = 1
if 239 < curByte then
byteCount = 4
elseif 223 < curByte then
byteCount = 3
elseif 128 < curByte then
byteCount = 2
elseif curByte == 10 then
byteCount = 1
else
byteCount = 1
end
local subStr = string.sub(sParam, nIndex, nIndex + byteCount - 1)
local charUnicodeNum = UFT8ToUnicode(subStr)
local bContains = false
local nAddCount = 1
for _, v in ipairs(strLengthConfig) do
local tbRange = v.tbRange
for _, range in ipairs(tbRange) do
if charUnicodeNum >= range[1] and charUnicodeNum <= range[2] then
bContains = true
nAddCount = v.nCount
break
end
end
if bContains then
break
end
end
nLength = nLength + nAddCount
nIndex = nIndex + byteCount
if nIndex > #sParam then
break
end
end
return nLength
end
local ParseByteString = function(sByte)
return {
string.byte(sByte, 1, -1)
}
end
local IsBitSet = function(tbByte, nIndex)
local nGroup64 = math.ceil(nIndex / 64) - 1
local nIndexInGroup64 = nIndex - nGroup64 * 64
local nGroup8 = math.ceil(nIndexInGroup64 / 8) - 1
local nIndexInGroup8 = nIndexInGroup64 - nGroup8 * 8
local nByteTableIndex = 8 - nGroup8 + nGroup64 * 8
if not tbByte[nByteTableIndex] then
return false
end
return 1 << nIndexInGroup8 - 1 & tbByte[nByteTableIndex] > 0
end
local GetBuildAttributeId = function(nGroupId, nLevel)
return nGroupId * 100000 + nLevel
end
local GetCharacterAttributeId = function(nCharId, nAdvance, nLevel)
return nCharId * 100000 + nAdvance * 1000 + nLevel
end
local GetDiscAttributeId = function(nGroupId, nPhase, nLevel)
return nGroupId * 1000 + nPhase * 100 + nLevel
end
local GetDiscExtraAttributeId = function(nGroupId, nStar)
return nGroupId * 10 + nStar
end
local GetPotentialId = function(nCharId, nIndex)
return 500000 + nCharId * 100 + nIndex
end
local ParseNoBrokenDesc = function(sDesc)
if Settings.sCurrentTxtLanguage == AllEnum.Language.EN or Settings.sCurrentTxtLanguage == AllEnum.Language.KR then
return sDesc
else
return "" .. sDesc .. ""
end
end
local SubDesc = function(str, nLevel, nCompareLevel, mapLinkParam)
local ConfigData = require("GameCore.Data.ConfigData")
local SubDescLink = function(originStr, mapParam)
if originStr == nil or originStr == "" then
return ""
end
local mapWord = {}
for word in string.gmatch(originStr, "##.-#%d%d%d%d#") do
if mapWord[word] == nil then
local sWordId = string.match(word, "%d%d%d%d")
local nWordId = tonumber(sWordId)
if nWordId == nil then
printError("词条 id 错误:" .. sWordId)
mapWord[word] = sWordId
else
local mapWordData = ConfigTable.GetData("Word", nWordId)
if mapWordData == nil or mapWordData.Icon == "" then
printError("该词条 id 找不到数据:" .. sWordId)
if mapWordData and mapWordData.Icon == "" then
printError("该词条 id 找不到Icon:" .. sWordId)
end
mapWord[word] = string.format("%s", sWordId)
elseif mapWordData.Type == GameEnum.wordLinkType.Word then
mapWord[word] = string.format("%s%s", mapWordData.Color, mapWordData.Id, mapWordData.Title, mapWordData.TitleIcon)
elseif mapWordData.Type == GameEnum.wordLinkType.Potential then
if mapParam == nil or mapParam.nCharId == nil then
printError("该<潜能>词条 id 找不到角色:" .. sWordId)
mapWord[word] = string.format("%s", sWordId)
else
local nPotentialId = GetPotentialId(mapParam.nCharId, tonumber(mapWordData.Param1))
local mapItemCfg = ConfigTable.GetData_Item(nPotentialId)
local sTitle = mapItemCfg and mapItemCfg.Title or mapWordData.Title
mapWord[word] = string.format("%s", mapWordData.Color, mapWordData.Id, sTitle)
end
end
end
end
end
for word, finalStr in pairs(mapWord) do
originStr = string.gsub(originStr, word, finalStr)
end
return originStr
end
local ParseHitDamageDesc = function(nHitDamageId, nHitDamageLevel)
local mapDamage = ConfigTable.GetData_HitDamage(nHitDamageId)
if not mapDamage then
return string.format("该 hit damage id 找不到数据:%s", nHitDamageId)
end
local nPercent = mapDamage.SkillPercentAmend[nHitDamageLevel]
local nAbs = mapDamage.SkillAbsAmend[nHitDamageLevel]
if not nPercent or not nAbs then
return string.format("该技能等级在 HitDamage 表中找不到数据, hit damage id:%d, level:%d", nHitDamageId, nHitDamageLevel)
end
nPercent = nPercent * ConfigData.IntFloatPrecision
nPercent = FormatNum(nPercent)
nAbs = FormatNum(nAbs)
local sPercent = nPercent == 0 and "" or tostring(nPercent) .. "%%"
local sAbs = nAbs == 0 and "" or tostring(nAbs)
if nPercent ~= 0 and nAbs ~= 0 then
return sPercent .. "+" .. sAbs
else
return sPercent .. sAbs
end
end
local GetValueKey = function(nDataId, nType, nValueLevel)
local ret = nDataId
if nType == GameEnum.levelTypeData.Exclusive or nType == GameEnum.levelTypeData.SkillSlot then
ret = nDataId + nValueLevel * 10
elseif nType == GameEnum.levelTypeData.OutfitPromote then
else
if nType == GameEnum.levelTypeData.OutfifBreak then
else
end
end
return ret
end
local ParseEffectDesc = function(nEffectId, nEffectLevel, nShowType)
local mapEffectCfgData = ConfigTable.GetData_Effect(nEffectId)
if mapEffectCfgData == nil then
return string.format("该EffectId找不到数据:%s", nEffectId)
end
local nValueKey = GetValueKey(nEffectId, mapEffectCfgData.levelTypeData, nEffectLevel)
local mapEffectValueData = ConfigTable.GetData("EffectValue", nValueKey)
if mapEffectValueData == nil then
return string.format("该EffectId和等级找不到Value数据:%s,%s", nEffectId, nEffectLevel)
end
local sValue = mapEffectValueData.EffectTypeParam1
local nValue = tonumber(sValue)
if nValue == nil then
return string.format("该EffectValueId配置的数据不支持显示:%s", nValueKey)
end
nValue = math.abs(nValue)
if nShowType == 1 then
nValue = nValue * 100
return nValue .. "%%"
end
return tostring(nValue)
end
local ParseOnceDesc = function(nOnceId, nOnceLevel, nShowType)
local mapCfgData = ConfigTable.GetData("OnceAdditionalAttribute", nOnceId)
if mapCfgData == nil then
return string.format("该OnceAdditionalAttributeId找不到数据:%s", nOnceId)
end
local nValueKey = GetValueKey(nOnceId, mapCfgData.levelTypeData, nOnceLevel)
local mapValueData = ConfigTable.GetData("OnceAdditionalAttributeValue", nValueKey)
if mapValueData == nil then
return string.format("该OnceAdditionalAttributeId和等级找不到Value数据:%s,%s,%s", nOnceId, nOnceLevel, nValueKey)
end
local nValue = mapValueData.Value1 * ConfigData.IntFloatPrecision
nValue = math.abs(nValue)
if nShowType == 1 then
nValue = nValue * 100
return nValue .. "%%"
end
return tostring(nValue)
end
local ParseShieldDesc = function(nShieldId, nShieldLevel, nShowType)
local mapCfgData = ConfigTable.GetData("Shield", nShieldId)
if mapCfgData == nil then
return string.format("该ShieldId找不到数据:%s", nShieldId)
end
local nValueKey = GetValueKey(nShieldId, mapCfgData.levelTypeData, nShieldLevel)
local mapValueData = ConfigTable.GetData("ShieldValue", nValueKey)
if mapValueData == nil then
return string.format("该ShieldId和等级找不到Value数据:%s,%s", nShieldId, nShieldLevel)
end
local nValue = mapValueData.ReferenceScale
nValue = nValue * ConfigData.IntFloatPrecision
nValue = math.abs(nValue)
if nShowType == 1 then
nValue = nValue * 100
return nValue .. "%%"
end
return tostring(nValue)
end
local ParseSriptDesc = function(nSriptId, nSriptLevel, nShowType)
local mapCfgData = ConfigTable.GetData("ScriptParameter", nSriptId)
if mapCfgData == nil then
return string.format("该SriptId找不到数据:%s", nSriptId)
end
local nValueKey = GetValueKey(nSriptId, mapCfgData.levelTypeData, nSriptLevel)
local mapValueData = ConfigTable.GetData("ScriptParameterValue", nValueKey)
if mapValueData == nil then
return string.format("该SriptId和等级找不到Value数据:%s,%s", nSriptId, nSriptLevel)
end
local nValue = mapValueData.CommonData
nValue = nValue * ConfigData.IntFloatPrecision
nValue = math.abs(nValue)
if nShowType == 1 then
nValue = nValue * 100
return nValue .. "%%"
end
return tostring(nValue)
end
local linkStr = SubDescLink(str, mapLinkParam)
if nLevel == nil then
return linkStr
end
local mapWord = {}
for word in string.gmatch(linkStr, "&.-&") do
local paramStr = string.gsub(word, "&", "")
print(paramStr)
local tbParam = string.split(paramStr, ",")
local sTable = tbParam[1]
local sKey = tbParam[2]
local sShowType = tbParam[3]
local nShowType = tonumber(sShowType)
if nShowType == nil then
nShowType = 0
end
if sTable == nil or sKey == nil then
mapWord[word] = string.format("配置错误,无法读取对应表名和ID:%s", word)
else
local nKey = tonumber(sKey)
if nKey == nil then
mapWord[word] = string.format("表ID配置错误,无法转为number:%s", word)
elseif sTable == "HitDamage" then
local subStr = ParseHitDamageDesc(nKey, nLevel)
if nCompareLevel ~= nil then
local sCompareStr = ParseHitDamageDesc(nKey, nCompareLevel)
subStr = string.format("%s(%s↑)", subStr, sCompareStr)
end
mapWord[word] = subStr
elseif sTable == "Effect" then
local subStr = ParseEffectDesc(nKey, nLevel, nShowType)
if nCompareLevel ~= nil then
local sCompareStr = ParseEffectDesc(nKey, nCompareLevel, nShowType)
subStr = string.format("%s(%s↑)", subStr, sCompareStr)
end
mapWord[word] = subStr
elseif sTable == "Once" then
local subStr = ParseOnceDesc(nKey, nLevel, nShowType)
if nCompareLevel ~= nil then
local sCompareStr = ParseOnceDesc(nKey, nCompareLevel, nShowType)
subStr = string.format("%s(%s↑)", subStr, sCompareStr)
end
mapWord[word] = subStr
elseif sTable == "Shield" then
local subStr = ParseShieldDesc(nKey, nLevel, nShowType)
if nCompareLevel ~= nil then
local sCompareStr = ParseShieldDesc(nKey, nCompareLevel, nShowType)
subStr = string.format("%s(%s↑)", subStr, sCompareStr)
end
mapWord[word] = subStr
elseif sTable == "Script" then
local subStr = ParseSriptDesc(nKey, nLevel, nShowType)
if nCompareLevel ~= nil then
local sCompareStr = ParseSriptDesc(nKey, nCompareLevel, nShowType)
subStr = string.format("%s(%s↑)", subStr, sCompareStr)
end
mapWord[word] = subStr
else
mapWord[word] = string.format("未支持的表名:%s", word)
end
end
end
for word, finalStr in pairs(mapWord) do
linkStr = string.gsub(linkStr, word, finalStr)
end
return ParseNoBrokenDesc(linkStr)
end
local ParseDesc = function(mapDescConfig, nCompareLevelType, nCompareLevel, bSimple, nOverrideLevel, mapLinkParam)
if mapDescConfig == nil then
printError("解析描述失败!")
return ""
end
local ConfigData = require("GameCore.Data.ConfigData")
local str = bSimple and mapDescConfig.BriefDesc or mapDescConfig.Desc
local GetValueKey = function(nDataId, nType, nValueLevel)
return nDataId + nValueLevel * 10
end
local TryAddMaxMark = function(mapValueTable, levelTypeData, nLevel, nId, sParameter)
if levelTypeData == GameEnum.levelTypeData.Exclusive then
local sMark = ConfigTable.GetUIText("Potential_ValueMax_HInt")
local nValue1 = GetValueKey(nId, levelTypeData, 1)
local nValue9 = GetValueKey(nId, levelTypeData, 9)
local nValue = GetValueKey(nId, levelTypeData, nLevel)
local mapValueData = mapValueTable[nValue]
local mapValueData1 = mapValueTable[nValue1]
local mapValueData9 = mapValueTable[nValue9]
if mapValueData == nil or mapValueData1 == nil or mapValueData9 == nil then
return
end
local sValue = mapValueData[sParameter]
local sValue1 = mapValueData1[sParameter]
local sValue9 = mapValueData9[sParameter]
if sValue ~= sValue1 and sValue == sValue9 then
return sMark
end
end
return
end
local SubDescLink = function(originStr, mapParam)
if originStr == nil or originStr == "" then
return ""
end
local mapWord = {}
for word in string.gmatch(originStr, "##.-#%d%d%d%d#") do
if mapWord[word] == nil then
local sWordId = string.match(word, "%d%d%d%d")
local nWordId = tonumber(sWordId)
if nWordId == nil then
printError("词条 id 错误:" .. sWordId)
mapWord[word] = sWordId
else
local mapWordData = ConfigTable.GetData("Word", nWordId)
if mapWordData == nil or mapWordData.Icon == "" then
printError("该词条 id 找不到数据:" .. sWordId)
if mapWordData and mapWordData.Icon == "" then
printError("该词条 id 找不到Icon:" .. sWordId)
end
mapWord[word] = string.format("%s", sWordId)
elseif mapWordData.Type == GameEnum.wordLinkType.Word then
mapWord[word] = string.format("%s%s", mapWordData.Color, mapWordData.Id, mapWordData.Title, mapWordData.TitleIcon)
elseif mapWordData.Type == GameEnum.wordLinkType.Potential then
if mapParam == nil or mapParam.nCharId == nil then
printError("该<潜能>词条 id 找不到角色:" .. sWordId)
mapWord[word] = string.format("%s", sWordId)
else
local nPotentialId = GetPotentialId(mapParam.nCharId, tonumber(mapWordData.Param1))
local mapItemCfg = ConfigTable.GetData_Item(nPotentialId)
local sTitle = mapItemCfg and mapItemCfg.Title or mapWordData.Title
mapWord[word] = string.format("%s", mapWordData.Color, mapWordData.Id, sTitle)
end
end
end
end
end
for word, finalStr in pairs(mapWord) do
originStr = string.gsub(originStr, word, finalStr)
end
return originStr
end
local linkStr = SubDescLink(str, mapLinkParam)
local ParseHitDamageDesc = function(nHitDamageId, nHitDamageLevel)
local sDesc = ""
local mapDamage = ConfigTable.GetData_HitDamage(nHitDamageId)
if not mapDamage then
sDesc = string.format("该 hit damage id 找不到数据:%s", nHitDamageId)
return sDesc
end
local levelType = mapDamage.levelTypeData
if levelType == GameEnum.levelTypeData.BreakCount then
if nHitDamageLevel < 1 then
nHitDamageLevel = 1 or nHitDamageLevel
end
elseif levelType == GameEnum.levelTypeData.None then
nHitDamageLevel = 1
end
local nPercent = mapDamage.SkillPercentAmend[nHitDamageLevel]
local nAbs = mapDamage.SkillAbsAmend[nHitDamageLevel]
if not nPercent or not nAbs then
sDesc = string.format("该技能等级在 HitDamage 表中找不到数据, hit damage id:%d, level:%d", nHitDamageId, nHitDamageLevel)
return sDesc
end
nPercent = nPercent * ConfigData.IntFloatPrecision
nPercent = FormatNum(nPercent)
nAbs = FormatNum(nAbs)
local sPercent = nPercent == 0 and "" or tostring(nPercent) .. "%%"
local sAbs = nAbs == 0 and "" or tostring(nAbs)
if nPercent ~= 0 and nAbs ~= 0 then
sDesc = sPercent .. "+" .. sAbs
else
sDesc = sPercent .. sAbs
end
return sDesc
end
local FormatValueShow = function(sValue, sShowType, sEnumType)
if sShowType == "Text" then
return sValue
elseif sShowType == "Enum" then
sEnumType = tostring(sEnumType)
if sEnumType ~= nil then
local tbEnum = CacheTable.GetData("_EnumDesc", sEnumType)
if tbEnum ~= nil then
local nEnumValue = tonumber(sValue)
if nEnumValue ~= nil then
if tbEnum[nEnumValue] then
return ConfigTable.GetUIText(tbEnum[nEnumValue])
else
printError(sEnumType .. "枚举未找到值:" .. nEnumValue)
return nil
end
else
printError("枚举值填写错误:" .. sValue)
return nil
end
else
printError("枚举类型填写错误:" .. sEnumType)
return nil
end
else
printError("枚举类型未填写")
return nil
end
else
local nValue = tonumber(sValue)
if nValue ~= nil then
local isIntFloat = sShowType == "10K" or sShowType == "10KPct" or sShowType == "10KHdPct"
local isPercent = sShowType == "Pct" or sShowType == "HdPct" or sShowType == "10KPct" or sShowType == "10KHdPct"
local multiHundred = sShowType == "HdPct" or sShowType == "10KHdPct"
nValue = isIntFloat and nValue * ConfigData.IntFloatPrecision or nValue
nValue = multiHundred and nValue * 100 or nValue
nValue = math.abs(nValue)
nValue = clearFloat(nValue)
local integer, decimal = math.modf(nValue)
sValue = decimal < 0.01 and tostring(integer) or tostring(nValue)
sValue = isPercent and sValue .. "%%" or sValue
return sValue
else
return nil
end
end
end
local ParseLevelUpDesc = function(sTable, nId, nLevel, sParameter, sShowType, sEnumType)
local sDesc, sErrorInfo
local mapCfgData = DataTable[sTable]
if mapCfgData ~= nil then
local sValueTable = sTable .. "Value"
local mapValueCfgData = DataTable[sValueTable]
if mapValueCfgData ~= nil then
local mapData = mapCfgData[nId]
if mapData ~= nil then
local nValueId = GetValueKey(nId, mapData.levelTypeData, nLevel)
local mapValueData = mapValueCfgData[nValueId]
if mapValueData ~= nil then
local sValue = mapValueData[sParameter]
if sValue ~= nil then
local sMark = TryAddMaxMark(mapValueCfgData, mapData.levelTypeData, nLevel, nId, sParameter)
sDesc = FormatValueShow(sValue, sShowType, sEnumType)
if sDesc == nil then
sErrorInfo = string.format("%s表中该ValueId配置的数据解析失败:%s", sValueTable, nValueId)
elseif sMark ~= nil then
sDesc = sDesc .. sMark
end
else
sErrorInfo = string.format("%s表中没有该字段:%s", sValueTable, sParameter)
end
else
sErrorInfo = string.format("%s表中该Id找不到数据:%s", sValueTable, nValueId)
end
else
sErrorInfo = string.format("%s表中该Id找不到数据:%s", sTable, nId)
end
else
sErrorInfo = string.format("找不到该配置表:%s", sValueTable)
end
else
sErrorInfo = string.format("找不到该配置表:%s", sTable)
end
if sErrorInfo ~= nil and sErrorInfo ~= "" then
printError(sErrorInfo)
sDesc = sErrorInfo
end
if sDesc == nil then
printError("描述解析失败")
sDesc = ""
end
return sDesc
end
local ParseNoLevelUpDesc = function(sTable, nId, sParameter, sShowType, sEnumType)
local sDesc, sErrorInfo
local mapCfgData = DataTable[sTable]
if mapCfgData ~= nil then
local mapData = mapCfgData[nId]
if mapData ~= nil then
local sValue = mapData[sParameter]
if sValue ~= nil then
sDesc = FormatValueShow(sValue, sShowType, sEnumType)
if sDesc == nil then
sErrorInfo = string.format("%s表中该Id配置的数据解析失败:%s", sTable, nId)
end
else
sErrorInfo = string.format("%s表中没有该字段:%s", sTable, sParameter)
end
else
sErrorInfo = string.format("%s表中该Id找不到数据:%s", sTable, nId)
end
else
sErrorInfo = string.format("找不到该配置表:%s", sTable)
end
if sErrorInfo ~= nil and sErrorInfo ~= "" then
printError(sErrorInfo)
sDesc = sErrorInfo
end
if sDesc == nil then
printError("描述解析失败")
sDesc = ""
end
return sDesc
end
local mapWord = {}
for word in string.gmatch(linkStr, "&.-&") do
local sParameterKeyOrigin = string.gsub(word, "&", "")
local sParameterKey, lang, langIdx = ParseLanguageParam(sParameterKeyOrigin)
local paramStr = mapDescConfig[sParameterKey]
local tbParam = string.split(paramStr, ",")
local sTable = tbParam[1]
local sParseType = tbParam[2]
local sKey = tbParam[3]
local sParameter = tbParam[4]
local sShowType = tbParam[5]
local sEnumType = tbParam[6]
if sTable == nil or sKey == nil then
mapWord[word] = string.format("配置错误,无法读取对应表名和ID:%s", word)
else
local mapCfgData = DataTable[sTable]
if mapCfgData ~= nil then
local nKey = tonumber(sKey)
if nKey == nil then
mapWord[word] = string.format("表ID配置错误,无法转为number:%s", word)
else
local mapData = mapCfgData[nKey]
if mapData ~= nil then
local nLevel = 1
nOverrideLevel = tonumber(nOverrideLevel)
if mapData.levelTypeData == GameEnum.levelTypeData.Exclusive then
nLevel = UTILS.QueryLevelInfo(mapData.LevelData, mapData.levelTypeData, mapData.LevelData)
else
local nCharId = tonumber(string.sub(sKey, 1, 3))
nLevel = UTILS.QueryLevelInfo(nCharId, mapData.levelTypeData, mapData.LevelData, mapData.MainOrSupport)
end
if (mapData.levelTypeData == GameEnum.levelTypeData.Exclusive or mapData.levelTypeData == GameEnum.levelTypeData.Note) and nOverrideLevel ~= nil then
nLevel = nOverrideLevel
end
if sParseType == "DamageNum" and sTable == "HitDamage" then
local subStr = ParseHitDamageDesc(nKey, nLevel)
subStr = LanguagePost(lang, langIdx, subStr)
if nCompareLevelType ~= nil and mapData.levelTypeData == nCompareLevelType and nCompareLevel ~= nil then
local sCompareStr = ParseHitDamageDesc(nKey, nCompareLevel)
sCompareStr = LanguagePost(lang, langIdx, sCompareStr)
if subStr ~= sCompareStr then
subStr = string.format("%s(%s↑)", subStr, sCompareStr)
end
end
mapWord[word] = subStr
elseif sParseType == "LevelUp" then
local subStr = ParseLevelUpDesc(sTable, nKey, nLevel, sParameter, sShowType, sEnumType)
subStr = LanguagePost(lang, langIdx, subStr)
if nCompareLevelType ~= nil and mapData.levelTypeData == nCompareLevelType and nCompareLevel ~= nil then
local sCompareStr = ParseLevelUpDesc(sTable, nKey, nCompareLevel, sParameter, sShowType, sEnumType)
sCompareStr = LanguagePost(lang, langIdx, sCompareStr)
if subStr ~= sCompareStr then
subStr = string.format("%s(%s↑)", subStr, sCompareStr)
end
end
mapWord[word] = subStr
elseif sParseType == "NoLevel" then
local str = ParseNoLevelUpDesc(sTable, nKey, sParameter, sShowType, sEnumType)
str = LanguagePost(lang, langIdx, str)
mapWord[word] = str
end
else
mapWord[word] = string.format("%s表中该Id找不到数据:%s", sTable, nKey)
end
end
else
mapWord[word] = string.format("找不到该配置表:%s", sTable)
end
end
end
for word, finalStr in pairs(mapWord) do
linkStr = string.gsub(linkStr, word, finalStr)
end
return ParseNoBrokenDesc(linkStr)
end
local ParseDiscDesc = function(originStr, mapSkill, mapSkillNext, nLayer, mapLinkParam)
originStr = UTILS.SubDesc(originStr, nil, nil, mapLinkParam)
local mapWord = {}
for word in string.gmatch(originStr, "{[0-9]*}") do
if mapWord[word] == nil then
local nCurLayer = nLayer
local sWordId = string.sub(word, 2, #word - 1)
local nWordId = tonumber(sWordId)
if nWordId == nil then
printError("wordId error:" .. sWordId)
mapWord[word] = sWordId
else
local fieldName = "Param" .. nWordId
if nCurLayer then
local nMaxStringCount = #mapSkill[fieldName]
if nCurLayer > nMaxStringCount then
nCurLayer = nMaxStringCount
end
for k, v in ipairs(mapSkill[fieldName]) do
if nCurLayer == k then
mapWord[word] = v
end
end
elseif mapSkillNext and mapSkill[fieldName] ~= mapSkillNext[fieldName] then
mapWord[word] = mapSkill[fieldName] .. "(" .. mapSkillNext[fieldName] .. "↑)"
else
mapWord[word] = mapSkill[fieldName]
end
if not mapWord[word] then
mapWord[word] = "{未找到参数配置}"
end
mapWord[word] = string.gsub(mapWord[word], "%%", "%%%%")
end
end
end
for word, finalStr in pairs(mapWord) do
originStr = string.gsub(originStr, word, finalStr)
end
return ParseNoBrokenDesc(originStr)
end
local ParseParamDesc = function(originStr, mapCfg, mapCfgNext, mapLinkParam, sColor)
originStr = UTILS.SubDesc(originStr, nil, nil, mapLinkParam)
local mapWord = {}
for word in string.gmatch(originStr, "{[0-9]*}") do
if mapWord[word] == nil then
local sWordId = string.sub(word, 2, #word - 1)
local nWordId = tonumber(sWordId)
if nWordId == nil then
printError("wordId error:" .. sWordId)
mapWord[word] = sWordId
else
local fieldName = "Param" .. nWordId
if mapCfgNext and mapCfg[fieldName] ~= mapCfgNext[fieldName] then
mapWord[word] = mapCfg[fieldName] .. "(" .. mapCfgNext[fieldName] .. "↑)"
elseif sColor then
mapWord[word] = "" .. mapCfg[fieldName] .. ""
else
mapWord[word] = mapCfg[fieldName]
end
if not mapWord[word] then
mapWord[word] = "{未找到参数配置}"
end
mapWord[word] = string.gsub(mapWord[word], "%%", "%%%%")
end
end
end
for word, finalStr in pairs(mapWord) do
originStr = string.gsub(originStr, word, finalStr)
end
return ParseNoBrokenDesc(originStr)
end
local ParseRewardItemCount = function(tbReward)
if nil == tbReward then
return -1
end
if #tbReward < 3 then
printError("物品数量配置错误,应有至少3个参数")
return -1
end
if #tbReward == 3 then
return tbReward[2]
elseif 3 < #tbReward then
local countTxt = tbReward[2] .. "~" .. tbReward[3]
return countTxt
end
return -1
end
local QueryLevelInfo = function(nId, nType, nParam1, nParam2)
local ret
ret = PlayerData.StarTower:QueryLevelInfo(nId, nType, nParam1, nParam2)
if ret == nil then
ret = PlayerData.Char:QueryLevelInfo(nId, nType, nParam1, nParam2)
end
return ret
end
local ParseLevelQuestTargetDesc = function(originStr, mapTarget)
local mapSkillType = {
[GameEnum.LevelQuestTargetType.CastSkill] = true,
[GameEnum.LevelQuestTargetType.CastSkillEnd] = true
}
local mapWord = {}
for word in string.gmatch(originStr, "{Param" .. "[0-9]*}") do
if mapWord[word] == nil then
local fieldName = string.sub(word, 2, #word - 1)
local sParam = mapTarget[fieldName]
if mapTarget.QuestType == GameEnum.LevelQuestTargetType.KillMonster and fieldName == "Param2" or mapTarget.QuestType == GameEnum.LevelQuestTargetType.KillMonsterByDamageTag and fieldName == "Param3" then
local nMonsterId = tonumber(sParam)
local sMonsterName = sParam
if nMonsterId then
local monsterData = ConfigTable.GetData("Monster", nMonsterId)
if monsterData then
local monsterSkin = ConfigTable.GetData("MonsterSkin", monsterData.FAId)
if monsterSkin then
local monsterManual = ConfigTable.GetData("MonsterManual", monsterSkin.MonsterManual)
if monsterManual then
sMonsterName = monsterManual.Name
end
end
end
end
sParam = sMonsterName
elseif mapSkillType[mapTarget.QuestType] and fieldName == "Param2" then
local nSkillId = tonumber(sParam)
local sSkillName = sParam
if nSkillId then
local mapCfg = ConfigTable.GetData("Skill", nSkillId)
if mapCfg then
sSkillName = mapCfg.Title
end
end
sParam = sSkillName
end
mapWord[word] = "" .. sParam .. ""
end
if not mapWord[word] then
mapWord[word] = "{未找到参数配置}"
end
mapWord[word] = string.gsub(mapWord[word], "%%", "%%%%")
end
for word, finalStr in pairs(mapWord) do
originStr = string.gsub(originStr, word, finalStr)
end
return originStr
end
local GetLevelQuestTargetProcess = function(mapTarget, nCur)
local mapSkipProcess = {
[GameEnum.LevelQuestTargetType.ReceiveTriggerOpId] = true,
[GameEnum.LevelQuestTargetType.Null] = true,
[GameEnum.LevelQuestTargetType.RecoverEnergy] = true,
[GameEnum.LevelQuestTargetType.KillAllMonster] = true
}
if mapSkipProcess[mapTarget.QuestType] then
return ""
end
if nCur then
return "(" .. nCur .. "/" .. mapTarget.Param1 .. ")"
else
return "(0/" .. mapTarget.Param1 .. ")"
end
end
local GetBezierPointByT = function(beginPos, handlePos, endPos, deltaTime)
local pow = (1 - deltaTime) ^ 2
local x = pow * beginPos.x + 2 * deltaTime * (1 - deltaTime) * handlePos.x + deltaTime * deltaTime * endPos.x
local y = pow * beginPos.y + 2 * deltaTime * (1 - deltaTime) * handlePos.y + deltaTime * deltaTime * endPos.y
local z = pow * beginPos.z + 2 * deltaTime * (1 - deltaTime) * handlePos.z + deltaTime * deltaTime * endPos.z
return x, y, z
end
local _
_, Red_Unable = ColorUtility.TryParseHtmlString("#BD3059")
_, Blue_Normal = ColorUtility.TryParseHtmlString("#264278")
_, Blue_Dark = ColorUtility.TryParseHtmlString("#3B62AE")
_, White_Normal = ColorUtility.TryParseHtmlString("#FAFAFA")
_, White_Dark = ColorUtility.TryParseHtmlString("#2d4257")
_, Gray_Dark = ColorUtility.TryParseHtmlString("#505c67")
local AddEffect = function(nCharId, nEffectId, nLevel, nUseCount)
if nUseCount == nil then
nUseCount = 0
end
local mapEftCfgData = ConfigTable.GetData_Effect(nEffectId)
if mapEftCfgData == nil then
printError("Effect Id missing" .. nEffectId)
return nil
end
local nEffectValueId = nEffectId
if mapEftCfgData.levelTypeData ~= GameEnum.levelTypeData.None then
nEffectValueId = nEffectValueId + nLevel * 10
end
local mapEftValueData = ConfigTable.GetData("EffectValue", nEffectValueId)
if mapEftValueData == nil then
printError("EffectValue Id missing" .. nEffectValueId)
return nil
end
local nEftRemainTimes = -1
if mapEftValueData.TakeEffectLimit ~= 0 then
nEftRemainTimes = mapEftValueData.TakeEffectLimit - nUseCount
if nEftRemainTimes <= 0 then
printLog("效果次数已用完:" .. nEffectId)
return nil
end
end
local nEffectUid = safe_call_cs_func(CS.AdventureModuleHelper.SetActorEffect, nCharId, nEffectId, nEftRemainTimes, 0)
return nEffectUid
end
local AddFateCardEft = function(nCharId, nEffectId, nRemainCount)
if nRemainCount == 0 then
printLog("效果次数已用完:" .. nEffectId)
return nil
end
local nEffectUid = safe_call_cs_func(CS.AdventureModuleHelper.SetActorEffect, nCharId, nEffectId, nRemainCount, 0)
return nEffectUid
end
local AddBuildEffect = function(mapCharEffect, mapDiscEffect, mapNoteEffect)
local retCharEffect = {}
local retDiscEffect = {}
local retNoteEffect = {}
for nCharId, mapEffect in pairs(mapCharEffect) do
if mapEffect[AllEnum.EffectType.Affinity] ~= nil then
for _, nEffectId in ipairs(mapEffect[AllEnum.EffectType.Affinity]) do
if retCharEffect[AllEnum.EffectType.Affinity] == nil then
retCharEffect[AllEnum.EffectType.Affinity] = {}
end
if retCharEffect[AllEnum.EffectType.Affinity][nEffectId] == nil then
retCharEffect[AllEnum.EffectType.Affinity][nEffectId] = {}
end
local nEftUid = UTILS.AddEffect(nCharId, nEffectId, 0, 0)
table.insert(retCharEffect[AllEnum.EffectType.Affinity][nEffectId], nEftUid)
end
end
if mapEffect[AllEnum.EffectType.Talent] ~= nil then
for _, nEffectId in ipairs(mapEffect[AllEnum.EffectType.Talent]) do
if retCharEffect[AllEnum.EffectType.Talent] == nil then
retCharEffect[AllEnum.EffectType.Talent] = {}
end
if retCharEffect[AllEnum.EffectType.Talent][nEffectId] == nil then
retCharEffect[AllEnum.EffectType.Talent][nEffectId] = {}
end
local nEftUid = UTILS.AddEffect(nCharId, nEffectId, 0, 0)
table.insert(retCharEffect[AllEnum.EffectType.Talent][nEffectId], nEftUid)
end
end
if mapEffect[AllEnum.EffectType.Potential] ~= nil then
for nPotentialId, tbPotentialData in pairs(mapEffect[AllEnum.EffectType.Potential]) do
for _, nEffectId in ipairs(tbPotentialData[1]) do
if retCharEffect[AllEnum.EffectType.Potential] == nil then
retCharEffect[AllEnum.EffectType.Potential] = {}
end
if retCharEffect[AllEnum.EffectType.Potential][nEffectId] == nil then
retCharEffect[AllEnum.EffectType.Potential][nEffectId] = {}
end
local nEftUid = UTILS.AddEffect(nCharId, nEffectId, tbPotentialData[2], 0)
table.insert(retCharEffect[AllEnum.EffectType.Potential][nEffectId], nEftUid)
end
end
end
if mapEffect[AllEnum.EffectType.Equipment] ~= nil then
for _, nEffectId in ipairs(mapEffect[AllEnum.EffectType.Equipment]) do
if retCharEffect[AllEnum.EffectType.Equipment] == nil then
retCharEffect[AllEnum.EffectType.Equipment] = {}
end
if retCharEffect[AllEnum.EffectType.Equipment][nEffectId] == nil then
retCharEffect[AllEnum.EffectType.Equipment][nEffectId] = {}
end
local nEftUid = UTILS.AddEffect(nCharId, nEffectId, 0, 0)
table.insert(retCharEffect[AllEnum.EffectType.Equipment][nEffectId], nEftUid)
end
end
if mapDiscEffect ~= nil then
for nDiscTid, tbDiscEffectId in pairs(mapDiscEffect) do
if retDiscEffect[nDiscTid] == nil then
retDiscEffect[nDiscTid] = {}
end
for _, mapEft in ipairs(tbDiscEffectId) do
if retDiscEffect[nDiscTid][mapEft[1]] == nil then
retDiscEffect[nDiscTid][mapEft[1]] = {}
end
local nEftUid = UTILS.AddEffect(nCharId, mapEft[1], mapEft[2], 0)
table.insert(retDiscEffect[nDiscTid][mapEft[1]], nEftUid)
end
end
end
if mapNoteEffect ~= nil then
for nNoteId, tbNoteEffectId in pairs(mapNoteEffect) do
if retNoteEffect[nNoteId] == nil then
retNoteEffect[nNoteId] = {}
end
for _, mapEft in ipairs(tbNoteEffectId) do
if retNoteEffect[nNoteId][mapEft[1]] == nil then
retNoteEffect[nNoteId][mapEft[1]] = {}
end
local nEftUid = UTILS.AddEffect(nCharId, mapEft[1], mapEft[2], 0)
table.insert(retNoteEffect[nNoteId][mapEft[1]], nEftUid)
end
end
end
end
return retCharEffect, retDiscEffect, retNoteEffect
end
local RemoveEffect = function(nEftUid, nCharId)
safe_call_cs_func(CS.AdventureModuleHelper.RemoveActorEffect, nCharId, nEftUid)
end
local GetBattleSamples = function(sFileName)
if sFileName == nil or sFileName == "" then
traceback("【战报】传入的 fileName 为空")
return
end
local lstBattleSamples = CS.AdventureModuleHelper.GetBattleSamples(sFileName)
local tbSamples = {}
if lstBattleSamples ~= nil then
local nCount = lstBattleSamples.Count - 1
local csList2Table = function(list)
if list == nil then
return {}
end
local nLstCount = list.Count - 1
local ret = {}
for i = 0, nLstCount do
table.insert(ret, list[i])
end
return ret
end
for i = 0, nCount do
local mapSample = {}
mapSample.FromSrcAtk = lstBattleSamples[i].fromSrcAtk
mapSample.FromPerkIntensityRatio = lstBattleSamples[i].fromPerkIntensityRatio
mapSample.FromSlotDmgRatio = lstBattleSamples[i].fromSlotDmgRatio
mapSample.FromEE = lstBattleSamples[i].fromEE
mapSample.FromGenDmgRatio = lstBattleSamples[i].fromGenDmgRatio
mapSample.FromDmgPlus = lstBattleSamples[i].fromDmgPlus
mapSample.FromCritRatio = lstBattleSamples[i].fromCritRatio
mapSample.FromFinalDmgRatio = lstBattleSamples[i].fromFinalDmgRatio
mapSample.FromFinalDmgPlus = lstBattleSamples[i].fromFinalDmgPlus
mapSample.ToErAmend = lstBattleSamples[i].toErAmend
mapSample.ToDefAmend = lstBattleSamples[i].toDefAmend
mapSample.ToRcdSlotDmgRatio = lstBattleSamples[i].toRcdSlotDmgRatio
mapSample.ToEERCD = lstBattleSamples[i].toEERCD
mapSample.ToGenDmgRcdRatio = lstBattleSamples[i].toGenDmgRcdRatio
mapSample.ToDmgPlusRcd = lstBattleSamples[i].toDmgPlusRcd
mapSample.Dmg = lstBattleSamples[i].dmg
mapSample.CritRate = lstBattleSamples[i].critRate
mapSample.Hp = lstBattleSamples[i].maxHP
mapSample.Log = {}
table.insert(tbSamples, mapSample)
end
end
return tbSamples
end
local GetCharDamageResult = function(tbCharId)
local tbResult = {}
for i = 1, #tbCharId do
local nCharId = tbCharId[i]
local nDamage = CS.AdventureModuleHelper.GetCharacterDamage(nCharId, false)
local actorInfo = {}
actorInfo.nCharId = nCharId
actorInfo.nDamage = nDamage
table.insert(tbResult, actorInfo)
end
return tbResult
end
local ClickItemGridWithTips = function(nTid, transform, bOnlyItemTips, bShowDepot, bShowJumpto, nHasCount)
local mapItemCfgData = ConfigTable.GetData_Item(nTid)
if mapItemCfgData == nil then
return
end
if mapItemCfgData.Type == GameEnum.itemType.Disc then
EventManager.Hit(EventId.OpenPanel, PanelId.DiscSample, nTid)
return
elseif mapItemCfgData.Type == GameEnum.itemType.Char then
EventManager.Hit(EventId.OpenPanel, PanelId.CharBgTrialPanel, PanelId.CharInfoTrial, nTid, {nTid}, true)
return
end
if bOnlyItemTips then
local mapData = {
nTid = nTid,
bShowDepot = bShowDepot,
bShowJumpto = bShowJumpto,
nHasCount = nHasCount
}
EventManager.Hit(EventId.OpenPanel, PanelId.ItemTips, transform, mapData)
else
local mapData = {
nTid = nTid,
bShowDepot = bShowDepot,
bShowJumpto = bShowJumpto,
nHasCount = nHasCount
}
EventManager.Hit(EventId.OpenPanel, PanelId.ItemTips, transform, mapData)
end
end
local CheckIsTipsPanel = function(nPanelId)
local tbAllTipsPanelId = {
PanelId.ItemTips,
PanelId.PerkTips,
PanelId.SkillTips,
PanelId.BtnTips,
PanelId.MonsterTips,
PanelId.EquipmentTips,
PanelId.DiscSkillTips
}
return table.indexof(tbAllTipsPanelId, nPanelId) > 0
end
local ClickWordLink = function(link, sWordId, mapLinkParam)
local nWordId = tonumber(sWordId)
local mapWordData = ConfigTable.GetData("Word", nWordId)
if mapWordData == nil then
if sWordId == nil then
printError("sWordId为空")
return
end
printError("wordId error:" .. sWordId)
return
end
if mapWordData.Type == GameEnum.wordLinkType.Word then
local mapData = {
nPerkId = 0,
nCount = 0,
bWordTip = true,
sWordId = sWordId
}
EventManager.Hit(EventId.OpenPanel, PanelId.PerkTips, link, mapData)
elseif mapWordData.Type == GameEnum.wordLinkType.Potential then
if mapLinkParam == nil or mapLinkParam.nCharId == nil then
printError("该<潜能>词条 id 找不到角色:" .. sWordId)
return
else
local nPotentialId = GetPotentialId(mapLinkParam.nCharId, tonumber(mapWordData.Param1))
EventManager.Hit(EventId.OpenPanel, PanelId.PotentialDetail, nPotentialId, mapLinkParam.nLevel, mapLinkParam.nAddLv)
end
end
end
local build_priority = function(selected, default_priority)
local priority = {}
local selected_map = {}
for _, field in ipairs(selected) do
table.insert(priority, field)
selected_map[field] = true
end
for _, field in ipairs(default_priority) do
if not selected_map[field] then
table.insert(priority, field)
end
end
return priority
end
local compare_roles = function(a, b, sort_priority, bOrder)
for i, field in ipairs(sort_priority) do
local va, vb = a[field], b[field]
if va ~= nil and vb ~= nil and va ~= vb then
if field == "Rare" or field == "nRarity" then
if i == 1 and bOrder then
return va > vb
else
return va < vb
end
elseif i == 1 and bOrder or field == "EET" or field == "nEET" then
return va < vb
else
return va > vb
end
end
end
return false
end
local compare_roles_SetFavoriteTop = function(a, b, sort_priority, bOrder)
local a_isFavorite = a.IsFavorite or false
local b_isFavorite = b.IsFavorite or false
if a_isFavorite ~= b_isFavorite then
return a_isFavorite and not b_isFavorite
end
for i, field in ipairs(sort_priority) do
local va, vb = a[field], b[field]
if va ~= nil and vb ~= nil and va ~= vb then
if field == "Rare" or field == "nRarity" then
if i == 1 and bOrder then
return va > vb
else
return va < vb
end
elseif i == 1 and bOrder or field == "EET" or field == "nEET" then
return va < vb
else
return va > vb
end
end
end
return false
end
local SortByPriority = function(items, selected_fields, default_priority, bOrder, bSetFavoriteTop)
local sort_priority = build_priority(selected_fields, default_priority)
if bSetFavoriteTop then
table.sort(items, function(a, b)
return compare_roles_SetFavoriteTop(a, b, sort_priority, bOrder)
end)
else
table.sort(items, function(a, b)
return compare_roles(a, b, sort_priority, bOrder)
end)
end
end
local GetDayRefreshTimeOffset = function()
local nNewDayTime = ConfigTable.GetConfigNumber("DailyRefreshOffsetHour") or 5
if 24 < nNewDayTime then
nNewDayTime = nNewDayTime % 24
end
return nNewDayTime
end
local SDK_Logout = function()
local SDKManager = CS.SDKManager.Instance
if SDKManager:IsSDKInit() ~= true then
return
end
SDKManager:SwitchAccount()
end
local SDK_ShowAgreement = function()
local SDKManager = CS.SDKManager.Instance
if SDKManager:IsSDKInit() ~= true then
return
end
local agreements = {}
local sChannel = NovaAPI.GetClientChannel()
if sChannel == "CN_Bilibili" or sChannel == "CN" or sChannel == "KOL" then
table.insert(agreements, "user_agreement")
table.insert(agreements, "privacy_agreement")
table.insert(agreements, "child_privacy_agreement")
else
table.insert(agreements, "user_agreement")
table.insert(agreements, "privacy_agreement")
table.insert(agreements, "minors_shop_agreement")
end
SDKManager.SDK:ShowAgreement(agreements)
end
local ServerChannel_CN = {
[1] = "cn_android_official",
[2] = "cn_ios_official",
[4] = "cn_android_bilibili",
[8] = "cn_harmony_official",
[16] = "cn_pc_official",
[32] = "cn_pc_bilibili"
}
local ServerChannel_JP = {
[1] = "jp_android_official",
[2] = "jp_ios_official",
[4] = "jp_android_onestore",
[8] = "jp_pc_official"
}
local ServerChannel_US = {
[1] = "us_android_official",
[2] = "us_ios_official",
[4] = "us_android_onestore",
[8] = "us_pc_official"
}
local ServerChannel_KR = {
[1] = "kr_android_official",
[2] = "kr_ios_official",
[4] = "kr_android_onestore",
[8] = "kr_pc_official"
}
local ServerChannel_TW = {
[1] = "tw_android_official",
[2] = "tw_ios_official",
[4] = "tw_android_onestore",
[8] = "tw_pc_official"
}
local GetChannelConfigList = function()
local resultList
local clientPublishRegion = CS.ClientConfig.ClientPublishRegion
if clientPublishRegion == CS.ClientPublishRegion.CN then
resultList = ServerChannel_CN
elseif clientPublishRegion == CS.ClientPublishRegion.JP then
resultList = ServerChannel_JP
elseif clientPublishRegion == CS.ClientPublishRegion.US then
resultList = ServerChannel_US
elseif clientPublishRegion == CS.ClientPublishRegion.KR then
resultList = ServerChannel_KR
else
if clientPublishRegion == CS.ClientPublishRegion.TW then
resultList = ServerChannel_TW
else
end
end
return resultList
end
local CheckChannel = function(channel)
local fullChannnel = CS.ClientConfig.FullClientPublishChannelName
local channelList = GetChannelConfigList()
if channelList == nil then
return false
end
local strChannel = channelList[channel]
if strChannel == nil then
return false
end
local tbClient = string.split(fullChannnel, "_")
local tbServer = string.split(strChannel, "_")
if tbClient[2] == nil or tbServer[2] == nil or tbClient[2] ~= tbServer[2] then
return false
end
if tbClient[3] == "taptap" then
tbClient[3] = "official"
end
if string.match(tbClient[3], "test") then
tbClient[3] = "official"
end
if tbClient[3] == nil or tbServer[3] == nil or tbClient[3] ~= tbServer[3] then
return false
end
return true
end
local CheckChannelList = function(channelList)
local sCurClientPublishRegion = CS.ClientConfig.ClientPublishRegion
if sCurClientPublishRegion == CS.ClientPublishRegion.Other then
return true
end
for i = 0, channelList.Count - 1 do
if CheckChannel(channelList[i]) then
return true
end
end
return false
end
local CheckChannelList_Notice = function(channelList)
local sCurClientPublishRegion = CS.ClientConfig.ClientPublishRegion
if sCurClientPublishRegion == CS.ClientPublishRegion.Other then
return true
end
for _, channel in ipairs(channelList) do
if CheckChannel(channel) then
return true
end
end
return false
end
local VersionCompare = function(v1, v2, num)
local v1List = string.split(v1, ".")
local v2List = string.split(v2, ".")
for i = 1, num do
if i > #v1List or i > #v2List then
if #v1List < #v2List then
return -1
elseif #v1List > #v2List then
return 1
else
return 0
end
end
local v1_num = tonumber(v1List[i]) or 0
local v2_num = tonumber(v2List[i]) or 0
if v1_num > v2_num then
return 1
elseif v1_num < v2_num then
return -1
end
end
return 0
end
local GetBBSUrl = function()
local result = false
local url = ""
local sChannel = NovaAPI.GetClientChannel()
if sChannel == "CN" or sChannel == "CN_Taptap" then
result = true
url = "https://bbs-stellasora.yostar.net/"
elseif sChannel == "CN_TEST_1" then
result = true
url = "https://staging-bbs.yostar.net/"
end
return result, url
end
local GetToolBoxUrl = function()
local result = false
local url = ""
local sChannel = NovaAPI.GetClientChannel()
local clientPublishRegion = CS.ClientConfig.ClientPublishRegion
if clientPublishRegion == CS.ClientPublishRegion.CN then
if sChannel == "CN" or sChannel == "CN_Bilibili" or sChannel == "CN_Taptap" then
result = true
url = "https://toolbox-stellasora.yostar.cn"
else
result = true
url = "https://staging-web-toolbox-stellasora.yostar.cn"
end
elseif clientPublishRegion == CS.ClientPublishRegion.TW then
if sChannel == "TW" then
result = true
url = "https://toolbox-stellasora.stargazer-games.com"
else
result = true
url = "https://staging-web-toolbox-stellasora.stargazer-games.com"
end
elseif clientPublishRegion == CS.ClientPublishRegion.JP then
if sChannel == "JP" then
result = true
url = "https://toolbox.stellasora.jp"
else
result = true
url = "https://staging-web-toolbox.stellasora.jp"
end
elseif clientPublishRegion == CS.ClientPublishRegion.US then
if sChannel == "EN" then
result = true
url = "https://toolbox.stellasora.global"
else
result = true
url = "https://staging-web-toolbox.stellasora.global"
end
elseif clientPublishRegion == CS.ClientPublishRegion.KR then
if sChannel == "KR" then
result = true
url = "https://toolbox.stellasora.kr"
else
result = true
url = "https://staging-web-toolbox.stellasora.kr"
end
end
return result, url
end
local GetExchangeCodeUrl = function()
local result = false
local url = ""
local sChannel = NovaAPI.GetClientChannel()
local clientPublishRegion = CS.ClientConfig.ClientPublishRegion
if clientPublishRegion == CS.ClientPublishRegion.CN then
elseif clientPublishRegion == CS.ClientPublishRegion.TW then
if sChannel == "TW" then
result = true
url = "https://stellasora.stargazer-games.com/redemption?type=webview"
else
result = true
url = "https://staging-web-stellasora.stargazer-games.com/redemption?type=webview"
end
elseif clientPublishRegion == CS.ClientPublishRegion.JP then
if sChannel == "JP" then
result = true
url = "https://stellasora.jp/serial_code?type=webview"
else
result = true
url = "https://staging-web.stellasora.jp/serial_code?type=webview"
end
elseif clientPublishRegion == CS.ClientPublishRegion.US then
if sChannel == "EN" then
result = true
url = "https://stellasora.global/gift?type=webview"
else
result = true
url = "https://staging-web.stellasora.global/gift?type=webview"
end
elseif clientPublishRegion == CS.ClientPublishRegion.KR then
if sChannel == "KR" then
result = true
url = "https://stellasora.kr/gift?type=webview"
else
result = true
url = "https://staging-web.stellasora.kr/gift?type=webview"
end
end
return result, url
end
_G.UTILS = {
DecodeChangeInfo = DecodeChangeInfo,
OpenReceiveByChangeInfo = OpenReceiveByChangeInfo,
OpenReceiveByDisplayItem = OpenReceiveByDisplayItem,
OpenReceiveByReward = OpenReceiveByReward,
GetParamStrLen = GetParamStrLen,
ParseByteString = ParseByteString,
IsBitSet = IsBitSet,
GetBuildAttributeId = GetBuildAttributeId,
GetCharacterAttributeId = GetCharacterAttributeId,
GetDiscAttributeId = GetDiscAttributeId,
GetDiscExtraAttributeId = GetDiscExtraAttributeId,
GetPotentialId = GetPotentialId,
SubDesc = SubDesc,
ParseDesc = ParseDesc,
ParseDiscDesc = ParseDiscDesc,
ParseParamDesc = ParseParamDesc,
ParseLevelQuestTargetDesc = ParseLevelQuestTargetDesc,
GetLevelQuestTargetProcess = GetLevelQuestTargetProcess,
ParseRewardItemCount = ParseRewardItemCount,
GetBezierPointByT = GetBezierPointByT,
AddEffect = AddEffect,
AddFateCardEft = AddFateCardEft,
AddBuildEffect = AddBuildEffect,
RemoveEffect = RemoveEffect,
GetBattleSamples = GetBattleSamples,
GetCharDamageResult = GetCharDamageResult,
ClickItemGridWithTips = ClickItemGridWithTips,
QueryLevelInfo = QueryLevelInfo,
SDK_Logout = SDK_Logout,
SDK_ShowAgreement = SDK_ShowAgreement,
ParseNoBrokenDesc = ParseNoBrokenDesc,
CheckIsTipsPanel = CheckIsTipsPanel,
ClickWordLink = ClickWordLink,
CheckChannelList = CheckChannelList,
VersionCompare = VersionCompare,
SortByPriority = SortByPriority,
GetDayRefreshTimeOffset = GetDayRefreshTimeOffset,
GetBBSUrl = GetBBSUrl,
GetToolBoxUrl = GetToolBoxUrl,
GetExchangeCodeUrl = GetExchangeCodeUrl,
CheckChannelList_Notice = CheckChannelList_Notice,
AddKrParticle = AddKrParticle,
LanguagePost = LanguagePost,
ParseLanguageParam = ParseLanguageParam,
RefreshRemainTime = RefreshRemainTime
}