Arch-kain

SyncBotsByName.lua

Jun 21st, 2021 (edited)
499
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local vars = {
  2.     ["Auto start"] = true,
  3.     ["Auto sync"]  = false,
  4. }
  5.  
  6. local keys = {
  7.     ["Sync bots now"] = 1,
  8.     ["Toggle auto sync"] = 2,
  9. }
  10.  
  11. local _print = print
  12. function Log   (...)       _print(... or "") end
  13. function Debug (...) ModDebug.Log(... or "") end
  14. function print (...) ModDebug.Log(... or "") end
  15. function Var   (name) return ModBase.GetExposedVariable(name) end
  16.  
  17. table.insert_once = function (table_name, element)
  18.     local found = true
  19.    
  20.     for k,v in pairs(table_name) do
  21.         if (v == element) then
  22.             found = false
  23.             break
  24.         end
  25.     end
  26.    
  27.     if (found) then
  28.         table.insert(table_name, element)
  29.         return true
  30.     end
  31.    
  32.     return false
  33. end
  34.  
  35. --------------
  36.  
  37.  
  38. function Expose ()
  39.     ModDebug.ClearLog()
  40.     print(">>> Expose")
  41.    
  42.     for k, v in pairs(vars) do
  43.         ModBase.ExposeVariable(k, v, ExposedVariableCallback)
  44.     end
  45.    
  46.     for k, v in pairs(keys) do
  47.         ModBase.ExposeKeybinding(k, v, OnKeyTrigger)
  48.     end
  49.    
  50.     print()
  51. end
  52.  
  53. function ExposedVariableCallback (value, name)
  54.     print(string.format("Exposed variable \"%s\" changed to: %s", name, tostring(value)))
  55. end
  56.  
  57.  
  58. --------------
  59.  
  60.  
  61. function BeforeLoad ()
  62.     print(">>> Loading...")
  63.     print("(Dev mode): ", ModDebug.IsDevMode())
  64.     print()
  65. end
  66.  
  67. function AfterLoad ()
  68.     Log("SyncBots: Loaded")
  69.     print(">>> Loaded")
  70.    
  71.     for k, v in pairs(vars) do
  72.         print(string.format("%s = %s", k, tostring(Var(k))))
  73.     end
  74.    
  75.     GetGroups()
  76. end
  77.  
  78.  
  79. --------------
  80. local timer = -5 --- timer start
  81. local timer_threshold = 5
  82. local timer_debug = 0
  83. local auto_sync_ispause = false
  84. local sync_isrunning = false
  85.  
  86.  
  87. function OnKeyTrigger (name)
  88.     print("\n", string.format("<<< \"%s\" Key triggered]", name))
  89.    
  90.     if name == "Sync bots now" then
  91.         if Var("Auto sync") and not sync_isrunning then
  92.             auto_sync_ispause = false
  93.         end
  94.        
  95.         timer = 0
  96.         SyncBots_Before()
  97.        
  98.        
  99.     elseif name == "Toggle auto sync" then
  100.         auto_sync_ispause = not auto_sync_ispause
  101.         print(string.format("(auto_sync_ispause = %s)", tostring(auto_sync_ispause)))
  102.     end
  103.    
  104. end
  105.  
  106. function OnUpdate (DeltaTime)
  107.     timer_debug = timer_debug + DeltaTime
  108.     if timer_debug >= 5 then
  109.         timer_debug = 0
  110.         print(string.format("(sync_isrunning = %s, auto_sync_ispause = %s)",
  111.             tostring(sync_isrunning), tostring(auto_sync_ispause)))
  112.     end
  113.    
  114.     if not Var("Auto sync") or sync_isrunning or auto_sync_ispause then
  115.         return
  116.     end
  117.    
  118.     timer = timer + DeltaTime
  119.     if timer >= timer_threshold then
  120.         timer = 0
  121.        
  122.         print("\n", "<<< [Auto sync]")
  123.         SyncBots_Before()
  124.     end
  125. end
  126.  
  127.  
  128.  
  129. --------------
  130.  
  131.  
  132.  
  133. function SyncBots_Before ()
  134.     -- print("[SyncBots_Before]")
  135.     print("sync_isrunning = ", sync_isrunning)
  136.    
  137.     -- if sync_isrunning then
  138.     --  return
  139.     -- end
  140.    
  141.     --- Check duplicates
  142.     local groups, duplicates = GetGroups()
  143.    
  144.    
  145.     --- Prompt confirm popup, if duplicates exist
  146.     if (#duplicates > 0) then
  147.         PromptDuplicatesWarning(groups, duplicates)
  148.     else
  149.         SyncBots(groups)
  150.     end
  151. end
  152.  
  153.  
  154. function GetGroups ()
  155.     local groups = {} --- (unique) groups name
  156.     local duplicates = {} --- (unique) groups that use the same name
  157.     ------print()
  158.    
  159.     for i, group_name in ipairs(ModBot.GetBotGroupNames()) do
  160.         local log = string.format("group (%s) : %s", i, group_name)
  161.        
  162.         --- if not inserted, another group has already this name
  163.         local inserted = table.insert_once(groups, group_name)
  164.         if not inserted then
  165.             log = log .. "    (DUPLICATE)"
  166.             table.insert_once(duplicates, group_name)
  167.         end
  168.        
  169.         ------print(log)
  170.     end
  171.    
  172.    
  173.     --- Debug: Log groups & duplicate names
  174.     ------print("\n", #groups, " groups:")
  175.     ------print("\t", table.concat(groups, "\n\t") )
  176.    
  177.     if (#duplicates > 0) then
  178.         ------print("\n", #duplicates, " duplicate groups:")
  179.         ------print("\t", table.concat(duplicates, "\n\t") )
  180.     end
  181.    
  182.     ------print()
  183.     return groups, duplicates
  184. end
  185.  
  186.  
  187. function PromptDuplicatesWarning (groups, duplicates)
  188.     print("\n", "[Prompt warning]")
  189.    
  190.     -- if Var("Auto sync") then
  191.     --  print("[Prompt note]")
  192.        
  193.     --  ModUI.ShowPopup("Auto sync has been paused",
  194.     --      "Press [Sync bot] to restart")
  195.     -- end
  196.    
  197.     ModUI.ShowPopupConfirm("WARNING: Duplicate group names!\n".."Sync these bots anyway ?",
  198.         "There are at least 2 groups with the same name, all their bots will be sync:\n" ..
  199.         "\"" .. table.concat(duplicates, "\", \"") .. "\"",
  200.        
  201.         --- YES : Sync anyway (all duplicate groups will be merged)
  202.         function ()
  203.             print("\n", "YES ! Sync them all")
  204.             auto_sync_ispause = false -- overwrite "cancel" response
  205.             SyncBots(groups)
  206.         end,
  207.        
  208.         --- NO : Ignore all bots in duplicate groups
  209.         function ()
  210.             print("\n", "NO ! Ignore duplicates")
  211.             auto_sync_ispause = false
  212.             SyncBots(groups, duplicates)
  213.         end)
  214.    
  215.     --- "Cancel"
  216.     --- Note : Will not wait confirmation
  217.      -- User must respond under {timer_threshold} sec before the next auto sync
  218.     print("after popup ?")
  219.     auto_sync_ispause = true
  220.     sync_isrunning = false
  221.     -- timer_threshold = 10
  222. end
  223.  
  224.  
  225. function SyncBots (groups, duplicates)
  226.     if not duplicates then duplicates = {} end
  227.    
  228.     print("[SyncBots]")
  229.     print("auto_sync_ispause = ", auto_sync_ispause)
  230.    
  231.     sync_isrunning = true
  232.    
  233.    
  234.     --- Find all bots with the same name to sync in each groups
  235.     for i, group_name in ipairs(groups) do
  236.        
  237.         --- ... unless the group's in duplicates list
  238.         local is_duplicate = false
  239.         for j, duplicate_name in ipairs(duplicates) do
  240.             if group_name == duplicate_name then
  241.                 is_duplicate = true
  242.                 break  
  243.             end
  244.         end
  245.        
  246.         if is_duplicate then -- debug
  247.             print("\n", group_name, "\t(DUPLICATE)")
  248.         else
  249.             print("\n", group_name)
  250.            
  251.             local bots_master = {}
  252.             local bots_id = ModBot.GetAllBotUIDsInGroup(group_name)
  253.             local original_count = #bots_id
  254.            
  255.             for j, bot_id in ipairs(bots_id) do
  256.                 local bot_name = ModBot.GetName(bot_id)
  257.                 local log = string.format("(%s)\t%s\t| %s", bot_id, bot_name, ModBot.GetState(bot_id))
  258.                 if j > original_count then
  259.                     print("\t", "—————")
  260.                 end
  261.                
  262.                 --- Ignore: Not name not allowed
  263.                 if (bot_name == "---" or bot_name:match("^Mk%d+$")) then
  264.                     -- print("\t[IGNORED NAME] !\t", log)
  265.                     goto continue
  266.                 end
  267.                
  268.                 --- Ignore: Bot's currently learning
  269.                 if ModBot.GetIsLearning(bot_id) then
  270.                     -- print("\t[LEARNING] !\t", log)
  271.                     goto continue
  272.                 end
  273.                
  274.                
  275.                 --- Get bot's script
  276.                 if not bots_master[bot_name] then
  277.                     --- Ignore: Pushed bot has no master → there is no script for it
  278.                     if j > original_count then
  279.                         -- print("\t[NO SCRIPT]!\t", log)
  280.                         goto continue
  281.                     end
  282.                    
  283.                     local script = ModBot.GetScriptSavegameFormat(bot_id)
  284.                    
  285.                     --- Ignore: Bot's script is empty ; push to the end of the list for re-check it after
  286.                     if script == "[]" then
  287.                         -- print("\t[NO SCRIPT]!\t", log, " >>> push back")
  288.                         table.insert(bots_id, bot_id)
  289.                         goto continue
  290.                     end
  291.                    
  292.                     bots_master[bot_name] = script
  293.                     -- print("\t[GetScript]<\t", log)
  294.                    
  295.                    
  296.                 --- Set bot's script
  297.                 else
  298.                     --- Ignored: Bot's currently running a script
  299.                     if ModBot.GetIsRunningScript(bot_id) then
  300.                         print("\t[RUNNING]  !\t", log)
  301.                         goto continue
  302.                     end
  303.                    
  304.                     --- [Debug only] Ignored: Bot's currenly moving -- busy (Moving, Shovel, etc.)
  305.                     --- Note : SetScript or StopScript don't work if bot's busy
  306.                     if ModBot.GetState(bot_id) ~= "None" then
  307.                         print("\t[BUSY]     :\t", log)
  308.                         goto continue
  309.                     end
  310.                    
  311.                     --- Set bot's script
  312.                     --- Note : Won't sync if the bot is moving
  313.                     print("\t[SetScript]>\t", log)
  314.                     ModBot.SetScriptSavegameFormat(bot_id, bots_master[bot_name])
  315.                 end
  316.                
  317.                
  318.                 --- Start it, if allowed
  319.                 if Var("Auto start") then
  320.                     ModBot.StartScript(bot_id)
  321.                 end
  322.                
  323.                 ::continue::
  324.             end
  325.         end
  326.     end
  327.    
  328.    
  329.    
  330.     sync_isrunning = false
  331.     print()
  332. end
RAW Paste Data