Advertisement
NJ5SkwAg

CH Auto Saver

Feb 3rd, 2016
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #Persistent
  2. #SingleInstance force
  3.  
  4. maxSaveCount := 60
  5.  
  6. menu, tray, add ; separator
  7. menu, tray, add, View_Saves
  8. menu, tray, Default, View_Saves
  9. Chars = ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
  10. StringCaseSense On
  11. return
  12.  
  13.  
  14. View_Saves:
  15.     IfNotExist info.txt
  16.         populateInfo()
  17.     compareInfo()
  18.     ; create the ListView with column names seperated by |s
  19.     Gui, Add, ListView, r60 w400 gMyListView, Filename|HZE|Immortal Damage|Solomon|Rubies|%A_Space%
  20.     ; gather a list of file names from a folder and put them into the ListView
  21.     Loop, read, info.txt
  22.     {
  23.         Loop, parse, A_LoopReadLine, %A_Tab%
  24.             field%A_Index% := A_LoopField
  25.         LV_Add("", field1, field2, field3, field4, field5)
  26.     }  
  27.     LV_ModifyCol(1)  ; auto-sizes column 1
  28.     LV_ModifyCol(2, "Integer")  ; for sorting purposes, indicate that column 2-5 are integers (-3)
  29.     LV_ModifyCol(3, "Float") ; immortal damage can be too big for integer, but float is slower
  30.     LV_ModifyCol(4, "Integer")
  31.     LV_ModifyCol(5, "Integer")
  32.     LV_ModifyCol(6, "0") ; dont display empty column
  33.     Gui, Show
  34. return
  35.  
  36.  
  37. MyListView:
  38.     if A_GuiEvent = DoubleClick
  39.     {
  40.         LV_GetText(RowText, A_EventInfo)  ; Get the text from the row's first field.
  41.         FileRead, codedSave, %RowText%
  42.         if ErrorLevel
  43.             Tooltip Error copying %RowText% to clipboard
  44.         else
  45.             ToolTip Copied %RowText% to clipboard
  46.         clipboard := codedSave
  47.         sleep 2000
  48.         ToolTip
  49.     }
  50. return
  51.  
  52.  
  53. GuiClose:
  54.     Gui, Destroy
  55. return
  56.  
  57.  
  58. OnClipboardChange:
  59.     if (A_EventInfo != 1)
  60.         return
  61.     codedSave := Clipboard
  62.     if (not InStr(codedSave, "Fe12NAfA3R6z4k0z"))
  63.         return
  64.     decodedsave := decodeSave(codedSave)
  65.     immortalDamage := json(decodedsave, "titanDamage")
  66.     if not immortalDamage
  67.         return
  68.     IfExist info.txt
  69.     {
  70.         compareInfo()
  71.         infoCount := 0
  72.         Loop, read, info.txt
  73.         {
  74.             infoCount++
  75.             Loop, parse, A_LoopReadLine, %A_Tab%
  76.                 field%A_Index% := A_LoopField
  77.             if (field3 = immortalDamage)
  78.                 return
  79.         }
  80.         if (infoCount >= maxSaveCount)
  81.             deleteOldestSave(infoCount + 1 - maxSaveCount)
  82.     }
  83.     filename := "CHSave" . A_Now . ".txt"
  84.     tooltip Clipboard copied to %filename%
  85.     FileAppend, %codedsave%, %filename%
  86.     HZE := json(decodedsave, "highestFinishedZonePersist")
  87.     solomon := json(decodedsave, "ancients.ancients.3.level")
  88.     rubies := json(decodedsave, "rubies")
  89.     FileAppend %filename%%A_Tab%%HZE%%A_Tab%%immortalDamage%%A_Tab%%solomon%%A_Tab%%rubies%`n, info.txt
  90.     sleep 2500
  91.     tooltip
  92. return
  93.  
  94.  
  95. deleteOldestSave(num)
  96. {
  97.     FileRead, contents, info.txt
  98.     if not ErrorLevel  ; Successfully loaded.
  99.     {
  100.         Sort, contents
  101.         deleteCount := 0
  102.         Loop, parse, contents, `n, `r
  103.         {
  104.             if (num < A_Index)
  105.                 break
  106.             filename := SubStr(A_LoopField, 1, 24)
  107.             fileDelete %filename%
  108.             deleteCount++
  109.             deleteLine%deleteCount% := filename
  110.         }
  111.         if deleteCount
  112.         {
  113.             file := ""
  114.             loop read, info.txt
  115.             {
  116.                 bDelete := 0
  117.                 filename := SubStr(A_LoopReadLine, 1, 24)
  118.                 loop % deleteCount
  119.                 {
  120.                     if (deleteLine%A_Index% = filename)
  121.                     {
  122.                         bDelete := 1
  123.                         break
  124.                     }
  125.                 }
  126.                 if not bDelete
  127.                     file .= A_LoopReadLine . "`n"
  128.             }
  129.             fileDelete info.txt
  130.             fileAppend, %file%, info.txt
  131.         }
  132.     }
  133. }
  134.  
  135.  
  136. compareInfo() ; gets called by View_Saves and OnClipboardChange
  137. {
  138.     saveCount := 0, infoCount := 0
  139.     Loop, CHSave*.*
  140.         saveCount++
  141.     Loop, read, info.txt
  142.         infoCount++
  143.     if saveCount = infoCount
  144.         return
  145.     if (saveCount > infoCount) ; more CHSave<date>s then what's in info.txt
  146.     {
  147.         tooltip Adding missing CHSave to info.txt
  148.         difference := saveCount - infoCount
  149.         Loop, CHSave*.*
  150.         {
  151.             saveFilename := A_LoopFileName
  152.             found := 0
  153.             Loop, read, info.txt
  154.             {
  155.                 if (saveFilename = SubStr(A_LoopReadLine, 1, 24))
  156.                 {
  157.                     found := 1
  158.                     break
  159.                 }
  160.             }
  161.             if not found
  162.             {
  163.                 FileRead, contents, %A_LoopFileName%
  164.                 decodedsave := decodeSave(contents)
  165.                 immortalDamage := json(decodedsave, "titanDamage")
  166.                 HZE := json(decodedsave, "highestFinishedZonePersist")
  167.                 solomon := json(decodedsave, "ancients.ancients.3.level")
  168.                 rubies := json(decodedsave, "rubies")
  169.                 FileAppend %A_LoopFileName%%A_Tab%%HZE%%A_Tab%%immortalDamage%%A_Tab%%solomon%%A_Tab%%rubies%`n, info.txt
  170.                 difference--
  171.                 if not difference
  172.                     break
  173.             }
  174.         }
  175.         tooltip
  176.         if difference
  177.             msgbox,,, Error adding missing CHSave to info.txt, 4
  178.     }
  179.     else if (saveCount < infoCount)
  180.     {
  181.         tooltip Removing entries from info.txt for nonexistant CHSave files
  182.         difference := infoCount - saveCount
  183.         missingCount := 0
  184.         Loop, read, info.txt
  185.         {
  186.             infoFilename := SubStr(A_LoopReadLine, 1, 24)
  187.             found := 0
  188.             Loop, CHSave*.*
  189.             {
  190.                 if (infoFilename = A_LoopFileName)
  191.                 {
  192.                     found := 1
  193.                     break
  194.                 }
  195.             }
  196.             if not found
  197.             {
  198.                 missingCount++
  199.                 missingLine%missingCount% := A_Index
  200.                 difference--
  201.             }
  202.             if not difference
  203.                 break
  204.         }
  205.         if missingCount
  206.         {
  207.             file := ""
  208.             loop read, info.txt
  209.             {
  210.                 currentLine := A_Index
  211.                 hasSave := 1
  212.                 loop % missingCount
  213.                 {
  214.                     if (missingLine%A_Index% = currentLine)
  215.                     {
  216.                         hasSave := 0
  217.                         break
  218.                     }
  219.                 }
  220.                 if hasSave
  221.                     file .= A_LoopReadLine . "`n"
  222.             }
  223.             fileDelete info.txt
  224.             fileAppend, %file%, info.txt
  225.         }
  226.         tooltip
  227.     }
  228. }
  229.  
  230.  
  231. populateInfo() ; gets called when there's no info.txt
  232. {
  233.     Loop, CHSave*.*
  234.     {
  235.         FileRead, contents, %A_LoopFileName%
  236.         if not ErrorLevel  ; Successfully loaded.
  237.         {
  238.             tooltip Populating info.txt... Decoding CHSave#%A_Index%
  239.             decodedSave := decodeSave(contents) ; by far the slowest operation
  240.             HZE := json(decodedSave, "highestFinishedZonePersist")
  241.             immortalDamage := json(decodedSave, "titanDamage")
  242.             solomon := json(decodedSave, "ancients.ancients.3.level")
  243.             rubies := json(decodedSave, "rubies")
  244.             FileAppend %A_LoopFileName%%A_Tab%%HZE%%A_Tab%%immortalDamage%%A_Tab%%solomon%%A_Tab%%rubies%`n, info.txt
  245.         }
  246.         else
  247.         {
  248.             tooltip
  249.             msgbox,,, error reading %A_LoopFileName%, 5
  250.         }
  251.     }
  252.     tooltip
  253. }
  254.  
  255.  
  256. decodeSave(codedSave)
  257. {
  258.     StringLeft, codedSaveLeft, codedSave, InStr(codedSave, "Fe12NAfA3R6z4k0z")
  259.     StringSplit, pseudoArray, codedSaveLeft
  260.     length := StrLen(codedSaveLeft) - 1
  261.     loop % length
  262.     {
  263.         if (mod(A_Index, 2) = 0)
  264.             continue
  265.         string .= pseudoArray%A_Index%
  266.     }
  267.     return InvBase64(string)
  268. }
  269.  
  270.  
  271. ; http://www.autohotkey.com/board/topic/5545-base64-coderdecoder/
  272. InvBase64(code)
  273. {
  274.    StringReplace code, code, =,,All
  275.    Loop Parse, code
  276.    {
  277.       If Mod(A_Index,4) = 1
  278.          buffer := DeCode(A_LoopField) << 18
  279.       Else If Mod(A_Index,4) = 2
  280.          buffer += DeCode(A_LoopField) << 12
  281.       Else If Mod(A_Index,4) = 3
  282.          buffer += DeCode(A_LoopField) << 6
  283.       Else {
  284.          buffer += DeCode(A_LoopField)
  285.          out := out . Chr(buffer>>16) . Chr(255 & buffer>>8) . Chr(255 & buffer)
  286.       }
  287.    }
  288.    If Mod(StrLen(code),4) = 0
  289.       Return out
  290.    If Mod(StrLen(code),4) = 2
  291.       Return out . Chr(buffer>>16)
  292.    Return out . Chr(buffer>>16) . Chr(255 & buffer>>8)
  293. }
  294.  
  295. DeCode(c)   ; c = a char in Chars ==> position [0,63]
  296. {
  297.    Global Chars
  298.    Return InStr(Chars,c,1) - 1
  299. }
  300.  
  301. ; http://www.autohotkey.com/board/topic/31619-json-readwrite-parser/
  302. ; https://github.com/polyethene/AutoHotkey-Scripts/blob/master/json.ahk
  303. json(ByRef js, s, v = "") {
  304.     j = %js%
  305.     Loop, Parse, s, .
  306.     {
  307.         p = 2
  308.         RegExMatch(A_LoopField, "([+\-]?)([^[]+)((?:\[\d+\])*)", q)
  309.         Loop {
  310.             If (!p := RegExMatch(j, "(?<!\\)(""|')([^\1]+?)(?<!\\)(?-1)\s*:\s*((\{(?:[^{}]++|(?-1))*\})|(\[(?:[^[\]]++|(?-1))*\])|"
  311.                 . "(?<!\\)(""|')[^\7]*?(?<!\\)(?-1)|[+\-]?\d+(?:\.\d*)?|true|false|null?)\s*(?:,|$|\})", x, p))
  312.                 Return
  313.             Else If (x2 == q2 or q2 == "*") {
  314.                 j = %x3%
  315.                 z += p + StrLen(x2) - 2
  316.                 If (q3 != "" and InStr(j, "[") == 1) {
  317.                     StringTrimRight, q3, q3, 1
  318.                     Loop, Parse, q3, ], [
  319.                     {
  320.                         z += 1 + RegExMatch(SubStr(j, 2, -1), "^(?:\s*((\[(?:[^[\]]++|(?-1))*\])|(\{(?:[^{\}]++|(?-1))*\})|[^,]*?)\s*(?:,|$)){" . SubStr(A_LoopField, 1) + 1 . "}", x)
  321.                         j = %x1%
  322.                     }
  323.                 }
  324.                 Break
  325.             }
  326.             Else p += StrLen(x)
  327.         }
  328.     }
  329.     If v !=
  330.     {
  331.         vs = " ;" just to fix my text editor coloring
  332.         If (RegExMatch(v, "^\s*(?:""|')*\s*([+\-]?\d+(?:\.\d*)?|true|false|null?)\s*(?:""|')*\s*$", vx)
  333.             and (vx1 + 0 or vx1 == 0 or vx1 == "true" or vx1 == "false" or vx1 == "null" or vx1 == "nul"))
  334.             vs := "", v := vx1
  335.         StringReplace, v, v, ", \", All
  336.         js := SubStr(js, 1, z := RegExMatch(js, ":\s*", zx, z) + StrLen(zx) - 1) . vs . v . vs . SubStr(js, z + StrLen(x3) + 1)
  337.     }
  338.     Return, j == "false" ? 0 : j == "true" ? 1 : j == "null" or j == "nul"
  339.         ? "" : SubStr(j, 1, 1) == """" ? SubStr(j, 2, -1) : j
  340. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement