You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
613 lines
26 KiB
613 lines
26 KiB
local _,rematch = ...
|
|
local L = rematch.localization
|
|
local C = rematch.constants
|
|
local settings = rematch.settings
|
|
rematch.teamStrings = {}
|
|
|
|
--[[
|
|
|
|
For exporting, importing (and send/receiving), groups and teams are converted to strings here.
|
|
|
|
Teams always take up one line, with \n in notes escaped when turned into a string:
|
|
|
|
With no preferences and no notes:
|
|
Team Name:<npcID>,<npcID>,<etc>:petTag1:petTag2:petTag3:
|
|
|
|
With preferences and no notes:
|
|
Team Name:<npcID>,<npcID>,<etc>:petTag1:petTag2:petTag3:P:<minHP>:<allowMM>:<expectedDD>:<minXP>:<maxXP>:
|
|
|
|
With no preferences and notes:
|
|
Team Name:<npcID>,<npcID>,<etc>:petTag1:petTag2:petTag3:N:<notes>
|
|
|
|
With preferences and notes:
|
|
Team Name:<npcID>,<npcID>,<etc>:petTag1:petTag2:petTag3:P:<minHP>:<allowMM>:<expectedDD>:<minXP>:<maxXP>:N:<notes>
|
|
|
|
* The name field is the only required field, but the colons (:) to fill out the other fields is required,
|
|
with the exception of P:<preferences> and N:<notes> they can be completely dropped.
|
|
* See utils\petTags.lua for format of petTags.
|
|
* npcIDs are converted to base 32, but preference values are not (and minXP and maxXP can be floats like 23.5)
|
|
|
|
When multiple teams are exported, their group headers are in one of three formats:
|
|
|
|
Legacy format (still supported):
|
|
__ Group Name __
|
|
|
|
With no preferences:
|
|
__ Group Name:<sort>:<icon>:<color>: __
|
|
|
|
With preferences:
|
|
__ Group Name:<sort>:<icon>:<color>:P:minHP:allowMM:expectedDD:maxHP:minXP:maxXP: __
|
|
|
|
* If the icon is a path like "Interface\Icons\INV_Misc_QuestionMark" it's converted to a fileID on export.
|
|
* The fileID is converted to base 32.
|
|
* When a Team Name or Group Name has a colon (:) it's replaced by a semicolon (;) on the export, and then
|
|
replaced back to a colon in import.
|
|
|
|
An export of a whole group of teams will then be:
|
|
|
|
__ Group Name:etc: __
|
|
|
|
Team Name:etc:
|
|
Team Name:etc:
|
|
Team Name:etc:
|
|
|
|
* With teams are exported they're in their current order defined by settings.GroupOrder.
|
|
* When all groups are exported (backup), it will export all groups in their order. On an import, it
|
|
will add them to the existing groups even if names match existing groups.
|
|
* When teams are imported, if any team shares a name with an existing team, an option will be given to
|
|
overwrite the existing teams or make new copies (append a number like (2) to make the name unique)
|
|
]]
|
|
|
|
-- returns the preference substring: P:minHP:allowMM:expectedDD:maxHP:minXP:maxXP:
|
|
-- note: none of these values are converted to base32 and minXP and maxXP can be floats (23.5)
|
|
function rematch.teamStrings:ExportPreferences(preferences)
|
|
if type(preferences)=="table" and settings.ExportIncludePreferences then
|
|
return format("P:%s:%s:%s:%s:%s:%s:",preferences.minHP or "",preferences.allowMM and "1" or "",preferences.expectedDD or "",preferences.maxHP or "",preferences.minXP or "",preferences.maxXP or "")
|
|
else
|
|
return ""
|
|
end
|
|
end
|
|
|
|
-- returns a team string for a single given teamID
|
|
function rematch.teamStrings:ExportTeam(teamID)
|
|
local team = teamID and rematch.savedTeams[teamID]
|
|
if not team then
|
|
return
|
|
end
|
|
|
|
-- a team can have multiple targets separated by commas: Team Name:123,987,456:ABCD:EFGH:IJKL:
|
|
local npcIDs = ""
|
|
if team.targets then
|
|
local targets = {}
|
|
for _,npcID in ipairs(team.targets) do
|
|
tinsert(targets,rematch.utils:ToBase32(npcID))
|
|
end
|
|
npcIDs = table.concat(targets,",")
|
|
end
|
|
|
|
-- base always exists name:npcID:petTag1:petTag2:petTag3:
|
|
local result = format("%s:%s:%s:%s:%s:",team.name:gsub(":",";"),npcIDs,team.tags[1] or "",team.tags[2] or "",team.tags[3] or "")
|
|
|
|
-- add preferences P:minHP:allowMM:expectedDD:maxHP:minXP:maxXP
|
|
result = result..rematch.teamStrings:ExportPreferences(rematch.preferences:GetTeamPreferences(teamID))
|
|
|
|
-- notes always at end
|
|
if team.notes and team.notes:trim():len()>0 and settings.ExportIncludeNotes then
|
|
result = result..format("N:%s",team.notes:trim():gsub("\n","\\n"))
|
|
end
|
|
|
|
return result
|
|
end
|
|
|
|
-- returns a multi-line string of the given teamID in a "plain text" format meant to be human readable
|
|
-- (plain text exports are never meant to be imported)
|
|
function rematch.teamStrings:ExportPlainTextTeam(teamID)
|
|
local team = teamID and rematch.savedTeams[teamID]
|
|
if not team then
|
|
return
|
|
end
|
|
|
|
-- team name is always first line by itself
|
|
local result = team.name.."\n"
|
|
-- second line if any targets (named differently than team) list them as "(Target Name, Other Target, etc.)"
|
|
if team.targets then
|
|
local targets = {}
|
|
for _,npcID in ipairs(team.targets) do
|
|
local name = rematch.targetInfo:GetNpcName(npcID)
|
|
if name and name~=team.name and name~=C.CACHE_RETRIEVING then -- only include target names if they aren't team name
|
|
tinsert(targets,name)
|
|
end
|
|
end
|
|
if #targets>0 then
|
|
result = result.."("..table.concat(targets,", ")..")\n"
|
|
end
|
|
end
|
|
-- line after team name (and possible target)
|
|
result = result..string.rep("-",team.name:len()).."\n"
|
|
-- next three lines are each pet in the team and their abilities (if applicable)
|
|
for i=1,3 do
|
|
local petID = team.pets[i]
|
|
local petTag = team.tags[i]
|
|
local petInfo = rematch.petInfo:Fetch(petID)
|
|
local name = petInfo.speciesName or petInfo.name or UNKNOWN
|
|
-- if abilities are in the tag (and not 000 for any abilities in any slot)
|
|
local abilities = petTag and petTag:match("^([012][012][012])")
|
|
if abilities and abilities~="000" then -- if all are 0, don't show abilities; but if 1 or 2 are 0, show as "any"; eg 1/1/any
|
|
name = name.." ("
|
|
for j=1,3 do
|
|
local ability = string.sub(abilities,j,j)
|
|
name = name..(ability=="0" and L["any"] or ability)..(j<3 and "," or "")
|
|
end
|
|
name = name..")"
|
|
end
|
|
result = result..name.."\n"
|
|
end
|
|
|
|
local preferences = type(team.preferences)=="table" and team.preferences
|
|
if settings.ExportIncludePreferences and preferences and rematch.utils:GetSize(preferences)>0 then
|
|
result = result..string.rep("-",team.name:len()).."\n".."Leveling preferences: "
|
|
local list = {}
|
|
if preferences.minHP then
|
|
tinsert(list,format(L["at least %d health"],preferences.minHP))
|
|
end
|
|
if preferences.allowMM then
|
|
tinsert(list,L["allow low-level Magic or Mechanical pets"])
|
|
end
|
|
if preferences.expectedDD then
|
|
tinsert(list,format(L["expect %s damage"],_G["BATTLE_PET_NAME_"..preferences.expectedDD] or UNKNOWN))
|
|
end
|
|
if preferences.maxHP then
|
|
tinsert(list,format(L["at most %d health"],preferences.maxHP))
|
|
end
|
|
if preferences.minXP then
|
|
tinsert(list,format(L["at least level %.f"],preferences.minXP))
|
|
end
|
|
if preferences.maxXP then
|
|
tinsert(list,format(L["at most level %.f"],preferences.maxXP))
|
|
end
|
|
if #list>0 then
|
|
result = result..table.concat(list,", ").."\n"
|
|
end
|
|
end
|
|
|
|
if settings.ExportIncludeNotes and team.notes then
|
|
result = result..string.rep("-",team.name:len()).."\n"..team.notes
|
|
end
|
|
|
|
return result:trim()
|
|
end
|
|
|
|
-- returns a string for a group header in format "__ name:sort:icon:color:showTab:[preferences] __"
|
|
-- all except name are optional, and preferences field only exists if group has preferences
|
|
function rematch.teamStrings:ExportHeader(groupID)
|
|
local group = groupID and rematch.savedGroups[groupID]
|
|
if group and group.name then
|
|
return format("__ %s:%s:%s:%s:%s:%s __",
|
|
group.name:gsub(":",";"):trim(),
|
|
group.sortMode or "",
|
|
rematch.utils:ToBase32(type(group.icon)=="number" and group.icon or GetFileIDFromPath(group.icon or "")) or "",
|
|
group.color or "",
|
|
group.showTab and "1" or "",
|
|
rematch.teamStrings:ExportPreferences(group.preferences)
|
|
)
|
|
end
|
|
end
|
|
|
|
-- returns an ordered table of strings for a group and all teams in the group (in table form
|
|
-- so it can spool to the multilineeditbox)
|
|
function rematch.teamStrings:ExportGroup(groupID)
|
|
local results = {}
|
|
|
|
local header = rematch.teamStrings:ExportHeader(groupID)
|
|
if header then
|
|
tinsert(results,header)
|
|
tinsert(results,"")
|
|
|
|
for _,teamID in ipairs(rematch.savedGroups[groupID].teams) do
|
|
local team = rematch.teamStrings:ExportTeam(teamID)
|
|
if team then
|
|
tinsert(results,team)
|
|
end
|
|
end
|
|
end
|
|
|
|
return results
|
|
end
|
|
|
|
-- returns an ordered table of all groups and teams
|
|
function rematch.teamStrings:ExportAll()
|
|
local results = {}
|
|
|
|
for _,groupID in ipairs(settings.GroupOrder) do
|
|
for _,teamString in pairs(rematch.teamStrings:ExportGroup(groupID)) do
|
|
tinsert(results,teamString)
|
|
end
|
|
tinsert(results,"")
|
|
end
|
|
-- remove trailing blank line
|
|
if #results>1 then
|
|
tremove(results,#results)
|
|
end
|
|
|
|
return results
|
|
end
|
|
|
|
-- analyzes the import string for groups and teams and returns numGroups, numTeams, numConflicts, numBad
|
|
function rematch.teamStrings:AnalyzeImport(import)
|
|
local numGroups = 0 -- number of group headers in the import
|
|
local numTeams = 0 -- number of teams in the import
|
|
local numConflicts = 0 -- number of teams/groups that share the name of an existing team in the import
|
|
local numBad = 0 -- number of unrecognized non-empty lines in the import
|
|
local foundFirst -- becomes "group" or "team"; if "team" found first then all groups ignored
|
|
|
|
-- read each line of the import
|
|
for line in ((import or "").."\n"):gmatch("(.-)\n") do
|
|
local test = line:trim()
|
|
local groupName = test:match("^__ (.-):*.* __$")
|
|
if groupName then -- this matches a group format, increment numGroups
|
|
numGroups = numGroups + 1
|
|
local existingGroupID = rematch.savedGroups:GetGroupIDByName(groupName)
|
|
-- if this group already exists (and it's not favorites or ungrouped which never conflict), increment numConflicts
|
|
if existingGroupID and existingGroupID~="group:favorites" and existingGroupID~="group:none" then
|
|
numConflicts = numConflicts + 1
|
|
end
|
|
if not foundFirst then
|
|
foundFirst = "group"
|
|
end
|
|
else
|
|
local teamName = test:match("^([^:]+):[%w,]*:%w*:%w*:%w*:")
|
|
if teamName then -- this line matches a team format, increment numTeams
|
|
numTeams = numTeams + 1
|
|
if rematch.savedTeams:GetTeamIDByName(teamName) then
|
|
numConflicts = numConflicts + 1 -- an existing team has this name, increment numConflicts
|
|
end
|
|
if not foundFirst then
|
|
foundFirst = "team"
|
|
end
|
|
elseif test:len()>0 then -- don't know what this is, increment numBad
|
|
numBad = numBad + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
-- if teams found before groups, ignore all groups and treat this as a multi-team import without groups
|
|
-- (so user is offered which group to put teams; otherwise these teams would have no place to go)
|
|
if foundFirst=="team" then
|
|
numGroups = 0
|
|
end
|
|
|
|
return numGroups,numTeams,numConflicts,numBad
|
|
end
|
|
|
|
-- imports a single team to the loadonly meta team and loads the team
|
|
function rematch.teamStrings:LoadOnly(import)
|
|
if type(import)~="string" then
|
|
return -- if import is not a string, do nothing and leave
|
|
end
|
|
|
|
-- confirm that only one team is being imported
|
|
local numGroups,numTeams = self:AnalyzeImport(import)
|
|
if not numGroups or (numGroups>0 and numTeams~=1) then
|
|
return -- this is not a single team import, leave
|
|
end
|
|
|
|
self:ImportTeam(import:trim(),"group:none",true)
|
|
|
|
rematch.loadTeam:LoadTeamID("loadonly")
|
|
end
|
|
|
|
-- imports the teams (possibly groups too) from the given import string
|
|
function rematch.teamStrings:Import(import)
|
|
|
|
if type(import)~="string" then
|
|
return -- if import is not a string, do nothing and leave
|
|
end
|
|
|
|
-- first analyze to figure out if groups are going to be made (first valid string is a group)
|
|
-- remember: if a team lists first, all groups are ignored. groups can ONLY be imported if the first
|
|
-- valid string is a group.
|
|
local numGroups,numTeams = self:AnalyzeImport(import)
|
|
|
|
-- for single team or multi team (not group) imports, the group to put teams is settings.LastSelectedGroup
|
|
-- here confirm setting is group:none if not defined or a no-longer-existing group
|
|
if not settings.LastSelectedGroup or not rematch.savedGroups[settings.LastSelectedGroup] then
|
|
settings.LastSelectedGroup = "group:none"
|
|
end
|
|
|
|
-- if ImportConflictOverwrite is true and any teams with same name are found, then overwrite existing team
|
|
local overwrite = settings.ImportConflictOverwrite
|
|
|
|
local groupID = settings.LastSelectedGroup
|
|
local firstGroupID
|
|
|
|
-- read each line of the import
|
|
for line in ((import or "").."\n"):gmatch("(.-)\n") do
|
|
local test = line:trim()
|
|
local groupLine = test:match("^(__ .+ __)$")
|
|
local teamLine = test:match("^([^:]+:[%w,]*:%w*:%w*:%w*:.*)$")
|
|
-- if groups can be picked up, look for groups to add (and teams will be added to these new groups)
|
|
if numGroups>0 then
|
|
if groupLine then
|
|
groupID = self:ImportGroup(groupLine:trim())
|
|
if not firstGroupID then
|
|
firstGroupID = groupID
|
|
end
|
|
settings.ExpandedGroups[groupID] = true
|
|
elseif teamLine then
|
|
self:ImportTeam(teamLine:trim(),groupID)
|
|
end
|
|
end
|
|
-- if no groups, then only look for teams and use the settings.LastSelectedGroup for where to put these
|
|
if numGroups==0 then
|
|
if teamLine then
|
|
local teamID = self:ImportTeam(teamLine:trim(),groupID)
|
|
rematch.savedTeams:TeamsChanged(true)
|
|
if numTeams==1 then -- if only importing one team, bling it
|
|
rematch.layout:SummonView("teams")
|
|
rematch.saveDialog:LoadAndBlingTeamID({teamID=teamID})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- if more than one team imported, scroll the group they were imported to top (first group if multi group)
|
|
if numTeams>1 or numGroups>0 then
|
|
rematch.layout:SummonView("teams")
|
|
rematch.saveDialog:BlingTeamIDOrGroupID(firstGroupID or groupID)
|
|
end
|
|
end
|
|
|
|
-- for the given tag (and excludePetIDs lookup table), return a petID and add to lookup if one found
|
|
local function findPetID(tag,excludePetIDs)
|
|
local petID = rematch.petTags:FindPetID(tag,excludePetIDs)
|
|
if type(petID)=="string" and petID:match("^BattlePet") then -- if an actual pet
|
|
excludePetIDs[petID] = true
|
|
end
|
|
return petID
|
|
end
|
|
|
|
-- takes the "extras" part of a string (preferences and notes) and returns preferences,notes as a table and string;
|
|
-- either or both can be nil
|
|
local function parseExtras(extras)
|
|
local preferences
|
|
local minHP,allowMM,expectedDD,maxHP,minXP,maxXP,notes = extras:match("^P:(%d*):(%d*):(%d*):(%d*):([%d%.]*):([%d%.]*):N:(.+)$")
|
|
if not minHP then
|
|
minHP,allowMM,expectedDD,maxHP,minXP,maxXP = extras:match("^P:(%d*):(%d*):(%d*):(%d*):([%d%.]*):([%d%.]*):$")
|
|
end
|
|
if not minHP then
|
|
notes = extras:match("^N:(.+)$")
|
|
end
|
|
if minHP then
|
|
preferences = {}
|
|
preferences.minHP = tonumber(minHP)
|
|
preferences.allowMM = tonumber(allowMM)==1 and true or nil
|
|
preferences.expectedDD = tonumber(expectedDD)
|
|
preferences.maxHP = tonumber(maxHP)
|
|
preferences.minXP = tonumber(minXP)
|
|
preferences.maxXP = tonumber(maxXP)
|
|
end
|
|
return preferences,notes
|
|
end
|
|
|
|
-- sets the sideline to the team in the import string
|
|
function rematch.teamStrings:SidelineTeamString(import,groupID)
|
|
-- test for extras (preferences/notes) first
|
|
local teamString,extras = import:match("^([^:]-:[%w,]*:%w*:%w*:%w*:)(.+)$")
|
|
if not teamString then -- no extras, test for just team
|
|
teamString = import:match("^([^:]-:[%w,]*:%w*:%w*:%w*:)$")
|
|
end
|
|
if not teamString then
|
|
return -- just team not found; not valid
|
|
end
|
|
|
|
-- at this point teamString is name:npcIDs:pet1:pet2:pet3: (and extras is any remainder)
|
|
|
|
local name,npcIDs,pet1,pet2,pet3 = teamString:match("([^:]+):([%w,]*):(%w*):(%w*):(%w*):$")
|
|
name=name:trim()
|
|
|
|
-- build sideline
|
|
rematch.savedTeams:Reset("sideline")
|
|
rematch.savedTeams.sideline.name = name
|
|
rematch.savedTeams.sideline.tags[1] = pet1
|
|
rematch.savedTeams.sideline.tags[2] = pet2
|
|
rematch.savedTeams.sideline.tags[3] = pet3
|
|
|
|
-- set groupID
|
|
rematch.savedTeams.sideline.groupID = groupID or "group:none"
|
|
if groupID=="group:favorites" then
|
|
rematch.savedTeams.sideline.homeID = "group:none"
|
|
rematch.savedTeams.sideline.favorite = true
|
|
end
|
|
|
|
-- find petIDs for each tag
|
|
local excludePetIDs = {}
|
|
rematch.savedTeams.sideline.pets[1] = findPetID(pet1,excludePetIDs)
|
|
rematch.savedTeams.sideline.pets[2] = findPetID(pet2,excludePetIDs)
|
|
rematch.savedTeams.sideline.pets[3] = findPetID(pet3,excludePetIDs)
|
|
|
|
-- set targets (comma-separated list)
|
|
if npcIDs:len()>0 then
|
|
rematch.savedTeams.sideline.targets = {}
|
|
for npcID in npcIDs:gmatch("[^,]+") do
|
|
local target = tonumber(npcID,32)
|
|
if target then
|
|
tinsert(rematch.savedTeams.sideline.targets,target)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- parse extras (preferences and notes) if any
|
|
if extras then
|
|
local preferences,notes = parseExtras(extras)
|
|
if preferences then
|
|
rematch.savedTeams.sideline.preferences = CopyTable(preferences)
|
|
end
|
|
if notes then
|
|
rematch.savedTeams.sideline.notes = notes:gsub("\\n","\n")
|
|
else
|
|
rematch.savedTeams.sideline.notes = nil
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
-- imports a single team to the given groupID
|
|
-- if loadOnly is true, then the team is imported into the "loadonly" meta team and not saved
|
|
function rematch.teamStrings:ImportTeam(import,groupID,loadOnly)
|
|
|
|
rematch.teamStrings:SidelineTeamString(import,groupID)
|
|
|
|
-- if team name already used, we're either making a copy (make name unique) or overwriting
|
|
-- (savedTeams:Create() call a TeamsChanged)
|
|
local existingTeamID = rematch.savedTeams:GetTeamIDByName(rematch.savedTeams.sideline.name)
|
|
local newTeamID
|
|
if loadOnly then -- if only loading team, copy sideline to loadonly meta team
|
|
--rematch.savedTeams.sideline.name = rematch.savedTeams:GetUniqueName(rematch.savedTeams.sideline.name)
|
|
rematch.savedTeams.loadonly = rematch.savedTeams.sideline
|
|
newTeamID = "loadonly"
|
|
elseif existingTeamID then
|
|
if settings.ImportConflictOverwrite then -- when overwriting, reuse old teamID
|
|
rematch.events:Fire("REMATCH_TEAM_OVERWRITTEN",existingTeamID)
|
|
rematch.savedTeams[existingTeamID] = rematch.savedTeams.sideline
|
|
newTeamID = existingTeamID
|
|
rematch.savedTeams:TeamsChanged()
|
|
else
|
|
rematch.savedTeams.sideline.name = rematch.savedTeams:GetUniqueName(rematch.savedTeams.sideline.name)
|
|
newTeamID = rematch.savedTeams:Create().teamID
|
|
end
|
|
else -- this is a new team with no conflict, create a new team
|
|
newTeamID = rematch.savedTeams:Create().teamID
|
|
end
|
|
|
|
-- if any of the chosen pets are below 25 (and QueueAutoImport enabled), then add them to queue
|
|
if settings.QueueAutoImport then
|
|
for i=1,3 do
|
|
local petID = rematch.savedTeams.sideline.pets[i]
|
|
local petInfo = rematch.petInfo:Fetch(petID)
|
|
if rematch.queue:PetIDCanLevel(petID) then
|
|
-- since queue won't have time to process/sort, making a manual check for each pass
|
|
local inQueue
|
|
for _,info in ipairs(settings.LevelingQueue) do
|
|
if info.petID==petID then
|
|
inQueue = true
|
|
break
|
|
end
|
|
end
|
|
if not inQueue then
|
|
rematch.queue:AddPetID(petID)
|
|
rematch.utils:WriteSystem(format(L["%s has been added to your leveling queue!"],petInfo.formattedName))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- returning teamID of team either created or overwritten
|
|
return newTeamID
|
|
end
|
|
|
|
-- creates a new group from the given __ name:sort:icon:color:[preferences] __ and returns the groupID that was created
|
|
function rematch.teamStrings:ImportGroup(import)
|
|
-- test for new group definition with preferences (extras) first
|
|
local groupName,sort,icon,color,showTab,extras = import:match("^__ ([^:]-):(%d*):(%w*):(%w*):(%w*):(.+) __$")
|
|
-- no match yet, try without preferences next
|
|
if not groupName then
|
|
groupName,sort,icon,color,showTab = import:match("^__ ([^:]-):(%d*):(%w*):(%w*):(%w*): __$")
|
|
end
|
|
-- still no match, try legacy with just group (was tab) name __
|
|
if not groupName then
|
|
groupName = import:match("^__ (.+) __$")
|
|
end
|
|
if not groupName then
|
|
return -- no group found in import string, leave
|
|
end
|
|
|
|
groupName = groupName:gsub(";",":"):trim()
|
|
|
|
-- if group has a valid name
|
|
if groupName:len()>0 then
|
|
local group
|
|
local existingGroupID = rematch.savedGroups:GetGroupIDByName(groupName)
|
|
if existingGroupID=="group:favorites" or existingGroupID=="group:none" then
|
|
group = rematch.savedGroups[existingGroupID] -- favorites and ungrouped always import into existing group
|
|
elseif existingGroupID and settings.ImportConflictOverwrite then
|
|
group = rematch.savedGroups[existingGroupID] -- other groups that share a name use existing one if overwrite chosen
|
|
else
|
|
group = rematch.savedGroups:Create(groupName) -- in all other cases create a new group (can be same name)
|
|
end
|
|
group.sortMode = tonumber(sort) or C.GROUP_SORT_ALPHA
|
|
group.icon = tonumber((icon or ""),32) or C.REMATCH_ICON
|
|
group.color = tonumber((color or ""),16) and color:trim() or nil
|
|
group.showTab = showTab~="" and true or nil
|
|
|
|
if extras then
|
|
group.preferences = parseExtras(extras:trim()) -- no notes support yet; but if so it'd be second return here
|
|
end
|
|
|
|
rematch.savedTeams:TeamsChanged()
|
|
return group.groupID
|
|
end
|
|
|
|
end
|
|
|
|
-- this creates and returns an ordered table with the teamID's string potentially split across multiple lines.
|
|
-- if a teamString is less than 254 characters, it only has one line.
|
|
-- when a line is incomplete (more are incoming) then it ends with \003.
|
|
-- when a line is a continuation (not the first line) then it begins with \002.
|
|
-- when an incoming team begins without \002 it should start a new team.
|
|
-- when an incoming line ends with \003 it should wait for the next line.
|
|
function rematch.teamStrings:SplitTeamStrings(teamID)
|
|
local teamString = self:ExportTeam(teamID)
|
|
if not teamString then
|
|
return -- teamID invalid
|
|
end
|
|
local results = {}
|
|
-- sending a team should always include preferences and notes
|
|
local oldIncludePreferences = settings.ExportIncludePreferences
|
|
local oldIncludeNotes = settings.ExportIncludeNotes
|
|
repeat
|
|
tinsert(results,teamString:sub(1,253))
|
|
teamString = teamString:sub(254)
|
|
until teamString:len()==0
|
|
if #results>1 then
|
|
for i=1,#results-1 do
|
|
results[i] = results[i].."\003"
|
|
end
|
|
for i=2,#results do
|
|
results[i] = "\002"..results[i]
|
|
end
|
|
end
|
|
return results
|
|
end
|
|
|
|
-- checks if it's time to prompt about backups and displays the dialog if so
|
|
function rematch.teamStrings:CheckForBackup()
|
|
if not settings.NoBackupReminder and not C_PetBattles.IsInBattle() and not InCombatLockdown() and not C_PetBattles.GetPVPMatchmakingInfo() then
|
|
local numTeams = rematch.savedTeams:GetNumTeams()
|
|
if type(settings.BackupCount)~="number" or settings.BackupCount==0 then
|
|
settings.BackupCount = numTeams
|
|
elseif numTeams > (settings.BackupCount+C.BACKUP_INTERVAL) then
|
|
settings.BackupCount = numTeams
|
|
rematch.dialog:Register("BackupTeams",{
|
|
title = L["Backup Teams"],
|
|
accept = YES,
|
|
cancel = NO,
|
|
layout = {"Text","SmallText","CheckButton"},
|
|
refreshFunc = function(self,info,subject,firstRun)
|
|
self.Text:SetText(format(L["You have %s%d\124r Rematch teams.\n\nWould you like to back them up now?"],C.HEX_WHITE,numTeams))
|
|
self.SmallText:SetText(L["Choosing Yes will export all teams to copy and paste in an email to yourself or someplace safe.\n\nYou can also do this at any time from the Teams button at the top of the Teams panel of Rematch."])
|
|
self.CheckButton:SetText(L["Don't Remind About Backups"])
|
|
self.CheckButton:SetChecked(settings.NoBackupReminder)
|
|
end,
|
|
changeFunc = function(self,info,subject,firstRun)
|
|
settings.NoBackupReminder = self.CheckButton:GetChecked()
|
|
end,
|
|
acceptFunc = function(self,info,subject)
|
|
rematch.timer:Start(0.1,function()
|
|
rematch.dialog:ShowDialog("ExportMultipleTeams")
|
|
end)
|
|
end,
|
|
})
|
|
rematch.dialog:Hide()
|
|
rematch.dialog:ShowDialog("BackupTeams")
|
|
end
|
|
end
|
|
end
|