khanat-opennel-code/code/ryzom/common/data_common/r2/r2_version.lua
botanic 80660b5146 FIX #200
dont crash when neldb is missing
2014-09-11 10:50:34 -07:00

496 lines
14 KiB
Lua

r2.Version = {}
local version = r2.Version
function r2.Version.checkVersion(scenarioVersionList, currentVersionList)
local undef = {}
local older = {}
local newer = {}
local ok = true
local k,v = next(scenarioVersionList, nil)
while k do
if (v ~= currentVersionList[k]) then
ok = false
if currentVersionList[k] == nil then
table.insert(undef, k)
elseif v < currentVersionList[k] then
table.insert(older, k)
else
table.insert(newer, k)
end
end
k,v = next(scenarioVersionList, k)
end
return ok, undef, older, newer
end
function r2.Version.getUndefComponent(scenarioVersionList, currentVersionList)
local undef = {}
local k,v = next(scenarioVersionList, nil)
while k do
if (v ~= currentVersionList[k] and currentVersionList[k] == nil ) then
table.insert(undef, k)
end
k,v = next(scenarioVersionList, k)
end
return true
end
local levelToString =
{
[0] = "20",
[1] = "50",
[2] = "100",
[3] = "150",
[4] = "200",
[5] = "250"
}
function r2.Version.save(filename)
local scenario = r2.Scenario
if scenario then
local scenarioList = r2.Version.getCurrentVersionList()
local update = false
local k,v = next(scenarioList, nil)
while k do
if (r2.Scenario.Versions[k] ~= v) then update = true end
k,v = next(scenarioList, k)
end
k,v = next(r2.Scenario.Versions, nil)
while k do
if (scenarioList[k] ~= v) then update = true end
k,v = next(r2.Scenario.Versions, k)
end
if update then
r2.requestSetGhostNode(scenario.InstanceId, "Versions", scenarioList)
end
local accessList = {}
local ok, level, err = r2.RingAccess.verifyScenario()
if not r2.RingAccess.LoadAnimation and not r2.getIsAnimationSession() then
r2.updateScenarioAck(ok, level, err.What)
end
accessList = r2.RingAccess.getAccessListAsString(level)
local values = {}
local date = os.date()
local firstLocationName = ""
local shortDescription = ""
local title = ""
local name = ""
local userName = r2:getUserEntityName()
local modifierMD5 = r2.getCharIdMd5()
local creatorName = ""
local rules = ""
local level = ""
local language = ""
local type = ""
local creatorMD5 =""
local createUserName = userName
local createDate = date
local otherCharAccess = "Full"
local nevraxScenario = "0"
local trialAllowed = "0"
local scenarioTag = ""
if r2.Scenario and r2.Scenario.Locations
and table.getn(r2.Scenario.Locations) > 0 and r2.Scenario.Locations[0].IslandName then
firstLocationName = r2.Scenario.Locations[0].IslandName
end
if r2.Scenario and r2.Scenario.Description then
--shortDescription =string.gsub(r2.Scenario.Description.ShortDescription, "\n", "\\n")
shortDescription = r2.Scenario.Description.ShortDescription
level = string.gsub(r2.Scenario.Description.LevelId, "\n", "\\n")
level = levelToString[tonumber(level)]
rules = string.gsub(r2.Scenario.AccessRules, "\n", "\\n")
if rules=="liberal" then
rules=i18n.get("uiR2EDliberal"):toUtf8()
elseif rules == "strict" then
rules=i18n.get("uiR2EDstrict"):toUtf8()
end
title = string.gsub(r2.Scenario.Description.Title, "\n", "\\n")
language = r2.Scenario.Language
type = r2.Scenario.Type
name = r2.Scenario.Name
if r2.Scenario.Ghost_Name then
name = r2.Scenario.Ghost_Name
end
if r2.Scenario.Description.Creator then
createUserName = r2.Scenario.Description.Creator
end
if r2.Scenario.Description.CreatorMD5 then
creatorMD5 = r2.Scenario.Description.CreatorMD5
end
if r2.Scenario.Description.CreationDate then
createDate = r2.Scenario.Description.CreationDate
end
if table.getn(r2.Scenario.Locations) > 0 then
initialIslandLocation = r2.Scenario.Locations[0].IslandName
initialEntryPoint = r2.Scenario.Locations[0].EntryPoint
initialSeason = r2.Scenario.Locations[0].Season
end
if r2.Scenario.Description.OtherCharAccess then
otherCharAccess = r2.Scenario.Description.OtherCharAccess
if otherCharAccess == "RoSOnly" then
if config.R2EDExtendedDebug ~= 1 then
if filename == "data/r2_buffer.dat" then
return false
else
r2.onSystemMessageReceived("BC_ML", "", "uiR2EDErrorRefuseToSaveRoS")
r2.requestNewAction(i18n.get("uiR2EDUpdatingScenarioToDefaultAccess"))
r2.requestSetNode(r2.Scenario.Description.InstanceId, "OtherCharAccess", "Full")
r2.requestEndAction()
return false
end
else
r2.onSystemMessageReceived("BC_ML", "", "Updating the system of Trial limitation")
r2.requestNewAction(i18n.get("uiR2EDUpdatingScenarioAccess"))
r2.requestSetNode(r2.Scenario.Description.InstanceId, "OtherCharAccess", "Full")
r2.requestSetNode(r2.Scenario.Description.InstanceId, "NevraxScenario", "1")
r2.requestSetNode(r2.Scenario.Description.InstanceId, "TrialAllowed", "1")
r2.requestSetNode(r2.Scenario.Description.InstanceId, "ScenarioTag", "")
r2.requestEndAction()
return false
end
end
end
if r2.Scenario.Description.NevraxScenario == tostring(1) then
nevraxScenario = r2.Scenario.Description.NevraxScenario
trialAllowed = r2.Scenario.Description.TrialAllowed
scenarioTag = r2.Scenario.Description.ScenarioTag
userName = "Ring(Nevrax)"
createUserName = userName
if config.R2EDExtendedDebug ~= 1 then
if filename == "data/r2_buffer.dat" then
return false
else
r2.onSystemMessageReceived("BC_ML", "", "uiR2EDErrorRefuseToSaveRoS")
r2.requestNewAction(i18n.get("uiR2EDUpdatingScenarioAccess"))
r2.requestSetNode(r2.Scenario.Description.InstanceId, "NevraxScenario", "0")
r2.requestSetNode(r2.Scenario.Description.InstanceId, "TrialAllowed", "0")
r2.requestSetNode(r2.Scenario.Description.InstanceId, "ScenarioTag", "")
r2.requestEndAction()
return false
end
end
end
end
table.insert(values, {Title = title})
table.insert(values, {Name = name})
table.insert(values, {ShortDescription = shortDescription})
table.insert(values, {FirstLocation = firstLocationName})
table.insert(values, {RingPointLevel = accessList})
table.insert(values, {CreateBy = createUserName})
table.insert(values, {CreatorMD5 = creatorMD5})
table.insert(values, {CreationDate = createDate})
table.insert(values, {ModifiedBy = userName})
table.insert(values, {ModifierMD5 = modifierMD5})
table.insert(values, {OtherCharAccess = otherCharAccess})
table.insert(values, {ModificationDate = date})
table.insert(values, {Rules = rules})
table.insert(values, {Level = level})
table.insert(values, {Type = type})
table.insert(values, {Language = language})
table.insert(values, {InitialIsland = initialIslandLocation})
table.insert(values, {InitialEntryPoint = initialEntryPoint})
table.insert(values, {InitialSeason = initialSeason})
if nevraxScenario == tostring(1) then
table.insert(values, {NevraxScenario = nevraxScenario})
table.insert(values, {TrialAllowed = trialAllowed})
table.insert(values, {ScenarioTag = scenarioTag})
end
r2.save(filename, values)
end
return true
end
local function updateVersionImpl(nodeList, scenarioVersionList, currentVersionFullList)
assert(nodeList)
assert(scenarioVersionList)
assert(currentVersionFullList)
local k,v = next(nodeList, nil)
while k do
-- go up in the class hierarchy, calling each redefinition of 'onUpdate' function
-- when a version change is detected
local currClassName = v.Class
-- look at a update function for this component or one of it's ancester
while currClassName ~= "" and currClassName ~= nil do
local currClass = r2.Classes[currClassName]
if not currClass then
debugInfo(colorTag(255, 0, 0) .. "Error can not update your scenario: the component"..currClassName.." seems to be obsolete")
return false
end
local scenarioVersionNode = defaulting(scenarioVersionList[currClassName], 0)
local currentVersionNode = defaulting(currentVersionFullList[currClassName], 0)
if currentVersionNode ~= scenarioVersionNode then
--
if scenarioVersionNode == nil then
debugInfo(colorTag(0, 255 ,255) .. "The component (".. v.Class .. ") does not exist anymore")
return false
elseif currentVersionNode == nil then
debugInfo(colorTag(0, 255 ,255) .. "The component (".. v.Class .. ") does not exist anymore")
return false
else
debugInfo(colorTag(0, 255 ,255) .. "Updating the component " .. v.InstanceId .. "(".. v.Class .. "/"..currClassName..") from ".. scenarioVersionNode .. " to " .. currentVersionNode ..".")
local updateFunc = currClass.updateVersion
if not updateFunc then
debugInfo( "Your scenario can not be updated. Because the component " .. v.Class .. " can not be updated (no update Function?).\n")
return false
end
local ok1, ok2 = pcall(updateFunc, v, scenarioVersionNode, currentVersionNode)
if not ok1 or not ok2 then
debugInfo( "Your scenario can not be updated. Because the component " .. v.Class .. " can not be updated.\n")
if not ok1 then
debugInfo(ok2)
end
return false
end
end
end
currClassName = currClass.BaseClass
end
k,v = next(nodeList, k)
end
return true
end
function r2.Version.updateVersion()
if r2.Translator == nil then
debugInfo("Syntax error")
return false
end
local scenarioInstance = r2.Scenario
if not scenarioInstance then return true end
local currentVersionFullList = r2.Version.getCurrentVersionFullList()
local scenarioVersionList = r2.Version.getScenarioVersionList()
local versionOk, undef, older, newer = r2.Version.checkVersion(scenarioVersionList, currentVersionFullList)
local modified = false
if not versionOk then
debugInfo(colorTag(0,255,25).."Begin Update")
local scenarioVersionName = scenarioInstance.VersionName
local currentVersionName = r2.Classes["Scenario"].VersionName
if scenarioVersionName == nil then scenarioVersionName = "0.0.0" end
if currentVersionName == nil then currentVersionName = "0.0.0" end
local str = "Updating the scenario from '"..scenarioVersionName.."' to '".. currentVersionName .."'.\nThe obsolete scenario will be saved in 'old_scenario.r2'"
printMsg(str)
local nodeList = r2.Version.getScenarioNodes(scenarioInstance)
assert(nodeList)
do
local k,v = next(undef, nil)
while k do
debugInfo(colorTag(0, 255 ,255) .. "The component ".. v .. " used in this scenario does not exist.")
k,v = next(undef, k)
end
end
do
local k,v = next(older, nil)
while k do
debugInfo(colorTag(0, 255 ,255) .. "The component ".. v .. " is too old (we will try to update it)")
k,v = next(older, k)
end
end
do
local k,v = next(newer, nil)
while k do
debugInfo(colorTag(0, 255 ,255) .. "The component ".. v .. " is too new (maybe wrong version?)")
k,v = next(newer, k)
end
end
if table.getn(undef) > 0 then
debugInfo(colorTag(255, 0, 0) .. "Error can not update your scenario: the scenario containse components that are not defined")
return true
end
local oldState = scenarioInstance.Ghost
scenarioInstance.Ghost = false
r2.save("old_scenario.r2")
scenarioInstance = r2.Scenario
scenarioInstance.Ghost = true
local syntaxOk, ok = pcall(updateVersionImpl, nodeList, scenarioVersionList, currentVersionFullList)
if not syntaxOk then
r2.print(ok)
ok = false
end
if ok then
-- ok
debugInfo(colorTag(0,255,25).."Update succced")
local currentVersionList = r2.Version.getCurrentVersionList()
r2.requestSetNode(scenarioInstance.InstanceId, "VersionName", currentVersionName)
r2.requestSetNode(scenarioInstance.InstanceId, "Versions", currentVersionList)
scenarioInstance.Ghost = oldState
r2.requestUploadCurrentScenario()
r2.clearActionHistoric() -- undo invalidated after a version update !!
modified = true
else
debugInfo(colorTag(255, 0, 0) .. "Errors occurs while updateing your scenario")
end
scenarioInstance.Ghost = oldState
debugInfo(colorTag(0,255,25).."End Update")
end
return not modified;
end
-- return Scenario Nodes - leaf first
function r2.Version.getScenarioNodes(node, nodeListParam)
assert(node)
if nodeListParam then nodeList = nodeListParam else nodeList = {} end
if not r2.isTable(node) then return nodeList end
local k,v = next(node, nil)
while k do
r2.Version.getScenarioNodes(v, nodeList)
k,v = next(node, k)
end
if node.InstanceId then
table.insert(nodeList, node)
if not node.Class then assert(nil) end
end
return nodeList
end
-- get the Current Version of sceanrio
function r2.Version.getCurrentVersionList()
local scenarionInstance = r2.Scenario
local versionList = {}
r2.Version._getCurrentVersionListImpl(scenarionInstance, versionList)
return versionList;
end
function r2.Version.getCurrentVersionFullList()
local versionList = {}
local classes = r2.Classes
local k, v = next(classes, nil)
while k do
if v.Version then
versionList[k] = v.Version
else
versionList[k] = 0
end
k, v = next(classes, k)
end
return versionList
end
function r2.Version._getCurrentVersionListImpl(node, versionList)
if ( type (node) == "string" or type(node) == "number") then return end
local k,v = next(node, nil)
if node.Class and not versionList[node.Class] then
if r2.Classes[node.Class] and r2.Classes[node.Class].Version then
versionList[node.Class] = r2.Classes[node.Class].Version
else
versionList[node.Class] = 0
end
end
while k do
r2.Version._getCurrentVersionListImpl(v, versionList);
k,v = next(node, k)
end
end
function r2.Version.getScenarioVersionList(scenarioNode)
local scenario = scenarioNode
if not scenario then scenario = r2.Scenario end
assert(scenario)
local versions = scenario.Versions
local versionList = {}
if versions == nil then
return r2.Version._getScenarioVersionListImpl(scenario, versionList)
else
local k,v = next(versions, nil)
while k do
versionList[k] = v
k,v = next(versions, k)
end
end
return versionList
end
function r2.Version._getScenarioVersionListImpl(node, versionList)
if ( type (node) == "string" or type(node) == "number") then return end
local k,v = next(node, nil)
if node.Class and not versionList[node.Class] then
versionList[node.Class] = 0
end
while k do
r2.Version._getScenarioVersionListImpl(v, versionList);
k,v = next(node, k)
end
return versionList
end
-- Version 0.0.0 -> prior to 7 dec 2005
-- version 0.0.1 prior to 7 dec 2005
-- Act.Version = 1
-- Act.ManualWeather
-- Act.WeatherValue
-- version 0.0.2 19 dec 2005
-- Act.Version = 2
-- Act.Behavior (Because Act changes type from BaseType to LogicAction
--
-- version 0.0.3 1 janv 2006
-- ActivityStep.Version=1
-- "Inactive" -> "Stand Still"