initial auto-xiv integration
continuous-integration/drone/push Build is passing
Details
|
@ -1,4 +1,4 @@
|
|||
garlandtools-dump/item/*
|
||||
garlandtools-dump/item/*
|
||||
garlandtools-dump/output-data.json
|
||||
garlandtools-dump/garlandtools-dump.exe
|
||||
gilgetter.exe
|
||||
|
|
|
@ -0,0 +1,265 @@
|
|||
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
|
||||
; #Warn ; Enable warnings to assist with detecting common errors.
|
||||
SendMode Event ; Recommended for new scripts due to its superior speed and reliability.
|
||||
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
|
||||
CoordMode, Mouse, Screen
|
||||
|
||||
^PgUp::
|
||||
retainerGetMaterials()
|
||||
ExitApp
|
||||
return
|
||||
|
||||
; End will kill the script entirely
|
||||
^End::
|
||||
ExitApp
|
||||
return
|
||||
|
||||
retainerGetMaterials() {
|
||||
ImageSearch, retainerListX, retainerListY, 530, 430, 1260, 1000, *150 images\retainernames.png
|
||||
if (ErrorLevel != 0) {
|
||||
WriteLog("ImageSearch for retainernames.png returned error level " + ErrorLevel)
|
||||
return
|
||||
}
|
||||
|
||||
currentRetainer := 2
|
||||
|
||||
MouseMove, retainerListX+72, retainerListY+60+((currentRetainer-1)*36), 3
|
||||
Sleep 300
|
||||
MouseClick ; Click retainer
|
||||
MouseClick
|
||||
Sleep 2500
|
||||
Click 1200, 250 ; Close dialog
|
||||
MouseClick
|
||||
Sleep 1000
|
||||
|
||||
ImageSearch, entrustWithdrawX, entrustWithdrawY, 940, 512, 1680, 700, *150 images\entrustwithdraw.png
|
||||
if (ErrorLevel != 0) {
|
||||
WriteLog("ImageSearch for entrustwithdraw.png returned error level " + ErrorLevel)
|
||||
return
|
||||
}
|
||||
|
||||
MouseMove, entrustWithdrawX+144, entrustWithdrawY+30, 3
|
||||
Sleep 300
|
||||
MouseClick ; Click entrust/withdraw
|
||||
MouseClick
|
||||
Sleep 400
|
||||
|
||||
ImageSearch, retainerInventoryX, retainerInventoryY, 1750, 10, 2560, 215, *150 images\retainerinventory.png
|
||||
if (ErrorLevel != 0) {
|
||||
WriteLog("ImageSearch for retainerinventory.png returned error level " + ErrorLevel)
|
||||
return
|
||||
}
|
||||
|
||||
; loop through items for this specific retainer
|
||||
|
||||
MouseMove, retainerInventoryX, retainerInventoryY, 3
|
||||
|
||||
; container 1
|
||||
|
||||
; container 2
|
||||
|
||||
; item
|
||||
row := 4
|
||||
col := 4 ; 69 in between
|
||||
|
||||
MouseMove, retainerInventoryX+404+(col-1)*69, retainerInventoryY+133+(row-1)*69, 3
|
||||
Sleep 300
|
||||
MouseClick, Right ;
|
||||
Sleep 100
|
||||
MouseClick, Right
|
||||
Sleep 100
|
||||
|
||||
|
||||
|
||||
; containers 3-4
|
||||
MouseMove, retainerInventoryX+362, retainerInventoryY+68, 3
|
||||
Sleep 300
|
||||
MouseClick ; Click the 2 button to switch to containers 3-4
|
||||
MouseClick
|
||||
|
||||
|
||||
; item
|
||||
row := 4
|
||||
col := 4 ; 69 in between
|
||||
|
||||
MouseMove, retainerInventoryX+46+(col-1)*69, retainerInventoryY+133+(row-1)*69, 3
|
||||
Sleep 300
|
||||
MouseClick, Right ;
|
||||
Sleep 100
|
||||
MouseClick, Right
|
||||
Sleep 100
|
||||
|
||||
; item
|
||||
row := 3
|
||||
col := 1 ; 69 in between
|
||||
|
||||
MouseMove, retainerInventoryX+46+(col-1)*69, retainerInventoryY+133+(row-1)*69, 3
|
||||
Sleep 300
|
||||
MouseClick, Right ;
|
||||
Sleep 100
|
||||
MouseClick, Right
|
||||
Sleep 100
|
||||
|
||||
; item
|
||||
row := 3
|
||||
col := 4 ; 69 in between
|
||||
|
||||
MouseMove, retainerInventoryX+46+(col-1)*69, retainerInventoryY+133+(row-1)*69, 3
|
||||
Sleep 300
|
||||
MouseClick, Right ;
|
||||
Sleep 100
|
||||
MouseClick, Right
|
||||
Sleep 100
|
||||
|
||||
; item
|
||||
row := 3
|
||||
col := 5 ; 69 in between
|
||||
|
||||
MouseMove, retainerInventoryX+46+(col-1)*69, retainerInventoryY+133+(row-1)*69, 3
|
||||
Sleep 300
|
||||
MouseClick, Right ;
|
||||
Sleep 100
|
||||
MouseClick, Right
|
||||
Sleep 100
|
||||
|
||||
; item
|
||||
row := 4
|
||||
col := 4 ; 69 in between
|
||||
|
||||
MouseMove, retainerInventoryX+46+(col-1)*69, retainerInventoryY+133+(row-1)*69, 3
|
||||
Sleep 300
|
||||
MouseClick, Right ;
|
||||
Sleep 100
|
||||
MouseClick, Right
|
||||
Sleep 100
|
||||
|
||||
; item
|
||||
row := 5
|
||||
col := 3 ; 69 in between
|
||||
|
||||
MouseMove, retainerInventoryX+46+(col-1)*69, retainerInventoryY+133+(row-1)*69, 3
|
||||
Sleep 300
|
||||
MouseClick, Right ;
|
||||
Sleep 100
|
||||
MouseClick, Right
|
||||
Sleep 100
|
||||
|
||||
|
||||
; container 5
|
||||
MouseMove, retainerInventoryX+607, retainerInventoryY+68, 3
|
||||
Sleep 300
|
||||
MouseClick ; Click the 2 button to switch to containers 3-4
|
||||
MouseClick
|
||||
}
|
||||
|
||||
|
||||
example() {
|
||||
MouseClick ; Click retainer
|
||||
MouseClick
|
||||
|
||||
Sleep 2500
|
||||
Click 1200, 250 ; Close dialog
|
||||
MouseClick
|
||||
Sleep 1000
|
||||
ImageSearch, outX, outY, 530, 430, 1660, 900, *150 images\sellitems.png
|
||||
if (ErrorLevel = 0) {
|
||||
MouseMove, outX+72, outY+20, 2
|
||||
Sleep 200
|
||||
MouseClick ; Click sellitems
|
||||
MouseClick
|
||||
Sleep 400
|
||||
|
||||
highestCursorY := 0 ; used to determine if we've reached the bottom of the list
|
||||
|
||||
Loop { ; loop through all items posted for sale
|
||||
|
||||
clipboard := "" ; clear the clipboard / pasted price
|
||||
|
||||
Sleep 500
|
||||
Send, {Numpad2} ; Move cursor to first/next item
|
||||
Sleep 300
|
||||
ImageSearch, outX, outY, 2050, 60, 2180, 620, *8 images\selected.png
|
||||
if (ErrorLevel = 0) {
|
||||
|
||||
; check if we have hit the bottom of the list and moved back up to the top
|
||||
if (outY < highestCursorY-15) { ; -15 to allow for tolerance in image search function
|
||||
break
|
||||
}
|
||||
|
||||
; handle case where only 1 item is posted by checking if highlighted item is near expected top of list area and it hasn't moved
|
||||
if (outY < 200) && (outY < highestCursorY+15) { ; +15 to allow for tolerance in image search function
|
||||
break
|
||||
}
|
||||
|
||||
highestCursorY = %outY% ; update highest cursory
|
||||
Send, {Numpad0} ; Select the item
|
||||
Sleep 100
|
||||
Send, {Numpad0} ; Select Adjust Price
|
||||
|
||||
|
||||
if (currentRetainer <= numNQRetainers) { ; If it's an HQ retainer, hold shift so penny pincher copies HQ price
|
||||
Send, {Shift down}
|
||||
}
|
||||
Sleep 75
|
||||
Send, {Numpad8} ; Move cursor to Compare Prices
|
||||
Sleep 85
|
||||
Send, {Numpad0} ; Select compare prices
|
||||
Sleep 850
|
||||
Send, {Esc} ; Close compare prices
|
||||
Sleep 200
|
||||
if (currentRetainer <= numNQRetainers) { ; If it's an HQ retainer, release shift
|
||||
Send, {Shift up}
|
||||
}
|
||||
|
||||
if (clipboard = "") { ; If nobody else has listed the item, just keep the same price. Also stop-gap in case dalamud / penny pincher isn't loaded correctly
|
||||
Send, {Esc} ; Close the item
|
||||
Sleep 200
|
||||
Continue ; Move on to next iteration
|
||||
}
|
||||
|
||||
ImageSearch, outX, outY, 1760, 360, 2220, 600, *150 images\askingprice.png
|
||||
if (ErrorLevel = 0) {
|
||||
MouseMove, outX+300, outY+15, 3
|
||||
Sleep 200
|
||||
MouseClick ; Click asking price input field
|
||||
Sleep 200
|
||||
SendRaw %clipboard% ; Update price
|
||||
Sleep 175
|
||||
|
||||
Send, {Enter} ; unlock cursor from numerical field
|
||||
Sleep 150
|
||||
Send, {Numpad2} ; move cursor down to confirm button
|
||||
Sleep 150
|
||||
Send, {Numpad2}
|
||||
Sleep 150
|
||||
Send, {Numpad2}
|
||||
Sleep 150
|
||||
Send, {Numpad0} ; Select confirm button
|
||||
}
|
||||
} else {
|
||||
break ; there are no items listed for sale
|
||||
}
|
||||
}
|
||||
|
||||
; Quit retainer
|
||||
Send, {Esc}
|
||||
Sleep 200
|
||||
Send, {Esc}
|
||||
Sleep 200
|
||||
Send, {Esc}
|
||||
Sleep 200
|
||||
Send, {Esc}
|
||||
Sleep 200
|
||||
Send, {Esc}
|
||||
Sleep 1000
|
||||
Click 1200, 250 ; Close dialog
|
||||
MouseClick
|
||||
Sleep 2100
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WriteLog(text) {
|
||||
FileAppend, % A_NowUTC ": " text "`n", logfile.txt ; can provide a full path to write to another directory
|
||||
}
|
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 395 B |
After Width: | Height: | Size: 873 B |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 792 B |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 11 KiB |
|
@ -1,10 +1,13 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
@ -85,9 +88,20 @@ func staleItemsPageHandler(w http.ResponseWriter, _ *http.Request) {
|
|||
func craftingCheckoutPageHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == "GET" {
|
||||
|
||||
type AutoXivItem struct {
|
||||
Row int
|
||||
Col int
|
||||
}
|
||||
|
||||
type Retainer struct {
|
||||
Name string
|
||||
ItemsToGet []inventorytools.Item
|
||||
RetainerNumber int
|
||||
Name string
|
||||
ItemsToGet []inventorytools.Item
|
||||
ContainerOne []AutoXivItem
|
||||
ContainerTwo []AutoXivItem
|
||||
ContainerThree []AutoXivItem
|
||||
ContainerFour []AutoXivItem
|
||||
ContainerFive []AutoXivItem
|
||||
}
|
||||
|
||||
type CraftingItem struct {
|
||||
|
@ -137,7 +151,9 @@ func craftingCheckoutPageHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
// Materials in retainer inventory and subtract
|
||||
retainerNumber := 0
|
||||
for _, retainer := range inventories.Retainers {
|
||||
retainerNumber++
|
||||
itemsToGet := make([]inventorytools.Item, 0)
|
||||
for _, item := range retainer.RetainerBags {
|
||||
if _, ok := craftingMaterialMap[item.ID]; ok {
|
||||
|
@ -160,7 +176,7 @@ func craftingCheckoutPageHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
if len(itemsToGet) > 0 {
|
||||
pageData.Retainers = append(pageData.Retainers, Retainer{Name: retainer.Name, ItemsToGet: itemsToGet})
|
||||
pageData.Retainers = append(pageData.Retainers, Retainer{Name: retainer.Name, RetainerNumber: retainerNumber, ItemsToGet: itemsToGet})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,6 +208,39 @@ func craftingCheckoutPageHandler(w http.ResponseWriter, r *http.Request) {
|
|||
log.Printf("failed to execute template: %v", err)
|
||||
}
|
||||
|
||||
// solve auto-xiv data for template
|
||||
|
||||
for i, retainer := range pageData.Retainers {
|
||||
for _, item := range retainer.ItemsToGet {
|
||||
|
||||
autoXivItem := AutoXivItem{}
|
||||
|
||||
autoXivItem.Row = int(math.Ceil(float64(item.SortedSlotIndex) / 5))
|
||||
autoXivItem.Col = item.SortedSlotIndex % 5
|
||||
if autoXivItem.Col == 0 {
|
||||
autoXivItem.Col = 5
|
||||
}
|
||||
|
||||
if item.SortedContainer == 1 {
|
||||
pageData.Retainers[i].ContainerOne = append(pageData.Retainers[i].ContainerOne, autoXivItem)
|
||||
} else if item.SortedContainer == 2 {
|
||||
pageData.Retainers[i].ContainerTwo = append(pageData.Retainers[i].ContainerTwo, autoXivItem)
|
||||
} else if item.SortedContainer == 3 {
|
||||
pageData.Retainers[i].ContainerThree = append(pageData.Retainers[i].ContainerThree, autoXivItem)
|
||||
} else if item.SortedContainer == 4 {
|
||||
pageData.Retainers[i].ContainerFour = append(pageData.Retainers[i].ContainerFour, autoXivItem)
|
||||
} else if item.SortedContainer == 5 {
|
||||
pageData.Retainers[i].ContainerFive = append(pageData.Retainers[i].ContainerFive, autoXivItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
withdrawMaterialsAhk = bytes.NewBuffer(nil)
|
||||
err = t.ExecuteTemplate(withdrawMaterialsAhk, "withdrawmaterials.ahk", pageData)
|
||||
if err != nil {
|
||||
log.Printf("failed to execute withdrawmaterials.ahk template: %v", err)
|
||||
}
|
||||
|
||||
} else if r.Method == "POST" {
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
|
@ -242,6 +291,22 @@ func craftingCheckoutPageHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
// http - GET /auto-xiv
|
||||
//
|
||||
// Downloads the .ahk file for withdrawing items
|
||||
func autoXivHandler(w http.ResponseWriter, _ *http.Request) {
|
||||
|
||||
w.Header().Set("Content-Disposition", "attachment; filename=withdraw-items.ahk")
|
||||
|
||||
b, err := io.ReadAll(withdrawMaterialsAhk)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
log.Printf("failed to read withdrawMaterialsAhk to bytes: %v", err)
|
||||
}
|
||||
|
||||
w.Write(b)
|
||||
}
|
||||
|
||||
// http - GET /full-price-update
|
||||
// Requests a full price update if criteria is met
|
||||
func fullPriceUpdateHandler(w http.ResponseWriter, _ *http.Request) {
|
||||
|
|
|
@ -26,7 +26,7 @@ func init() {
|
|||
if err != nil {
|
||||
log.Fatal("Getting appdata directory failed:", err)
|
||||
}
|
||||
inventoriesFilePath = fmt.Sprintf("%s/XIVLauncher/pluginConfigs/InventoryTools/inventories.json", appDataDir)
|
||||
inventoriesFilePath = fmt.Sprintf("%s/XIVLauncher/pluginConfigs/GilGetterPlugin/inventories.json", appDataDir)
|
||||
|
||||
setRetainers() // Create your own definitions that satisfy the retainer struct - see README.md
|
||||
}
|
||||
|
|
7
main.go
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
@ -32,6 +33,7 @@ var (
|
|||
priceUpdateProgress int // an integer from 0-100 indicating percentage of any ongoing Universalis update. If 100, then the update is complete.
|
||||
world, datacenter, universalisPriceEndpoint string // filter Universalis to this world name
|
||||
priceUpdateErrors map[int]bool // if an item ID exists in here, then there was an error when updating its price. Gets reset after priceUpdateQueue is drained.
|
||||
withdrawMaterialsAhk *bytes.Buffer // contains the processed ahk template of items that need to be withdrawn for crafting
|
||||
|
||||
retainers []string // contains name of retainers
|
||||
craftingCheckoutItemIDs []int // The item IDs which were selected on the crafting checkout page, used for shopping list
|
||||
|
@ -186,6 +188,8 @@ func init() {
|
|||
lastFullPriceUpdateTime = time.Now()
|
||||
|
||||
itemSlice = make([]MarketItem, 0)
|
||||
|
||||
withdrawMaterialsAhk = bytes.NewBuffer(nil)
|
||||
}
|
||||
|
||||
// HTTP routing
|
||||
|
@ -200,6 +204,9 @@ func main() {
|
|||
// Serve public static files such as css, js, images
|
||||
http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(http.Dir("public"))))
|
||||
|
||||
// Download .ahk file
|
||||
http.HandleFunc("/auto-xiv", autoXivHandler)
|
||||
|
||||
// Page Handlers
|
||||
// Anything that is responsible for the base elements of a viewable web page
|
||||
http.HandleFunc("/", homePageHandler)
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
</table>
|
||||
|
||||
<h2 class="ui header">Materials From Retainers</h2>
|
||||
<a href="/auto-xiv">Auto XIV</a>
|
||||
{{ range .Retainers }}
|
||||
<h3 class="ui header">{{ .Name }}</h4>
|
||||
<table class="ui compact celled striped table">
|
||||
|
|
|
@ -0,0 +1,264 @@
|
|||
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
|
||||
; #Warn ; Enable warnings to assist with detecting common errors.
|
||||
SendMode Event ; Recommended for new scripts due to its superior speed and reliability.
|
||||
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
|
||||
CoordMode, Mouse, Screen
|
||||
|
||||
^PgUp::
|
||||
retainerGetMaterials()
|
||||
ExitApp
|
||||
return
|
||||
|
||||
; End will kill the script entirely
|
||||
^End::
|
||||
ExitApp
|
||||
return
|
||||
|
||||
retainerGetMaterials() {
|
||||
ImageSearch, retainerListX, retainerListY, 530, 430, 1260, 1000, *150 images\retainernames.png
|
||||
if (ErrorLevel != 0) {
|
||||
WriteLog("ImageSearch for retainernames.png returned error level " + ErrorLevel)
|
||||
return
|
||||
}
|
||||
|
||||
{{ range .Retainers }}
|
||||
|
||||
currentRetainer := {{ .RetainerNumber }}
|
||||
|
||||
MouseMove, retainerListX+72, retainerListY+60+((currentRetainer-1)*36), 3
|
||||
Sleep 300
|
||||
MouseClick ; Click retainer
|
||||
MouseClick
|
||||
Sleep 2500
|
||||
Click 1200, 250 ; Close dialog
|
||||
MouseClick
|
||||
Sleep 1000
|
||||
|
||||
ImageSearch, entrustWithdrawX, entrustWithdrawY, 940, 512, 1680, 700, *150 images\entrustwithdraw.png
|
||||
if (ErrorLevel != 0) {
|
||||
WriteLog("ImageSearch for entrustwithdraw.png returned error level " + ErrorLevel)
|
||||
return
|
||||
}
|
||||
|
||||
MouseMove, entrustWithdrawX+144, entrustWithdrawY+30, 3
|
||||
Sleep 300
|
||||
MouseClick ; Click entrust/withdraw
|
||||
MouseClick
|
||||
Sleep 400
|
||||
|
||||
ImageSearch, retainerInventoryX, retainerInventoryY, 1750, 10, 2560, 215, *150 images\retainerinventory.png
|
||||
if (ErrorLevel != 0) {
|
||||
WriteLog("ImageSearch for retainerinventory.png returned error level " + ErrorLevel)
|
||||
return
|
||||
}
|
||||
|
||||
; loop through items for this specific retainer
|
||||
|
||||
MouseMove, retainerInventoryX, retainerInventoryY, 3
|
||||
|
||||
; container 1 - offset 46
|
||||
{{ range .ContainerOne }}
|
||||
row := {{ .Row }}
|
||||
col := {{ .Col }}
|
||||
MouseMove, retainerInventoryX+46+(col-1)*69, retainerInventoryY+133+(row-1)*69, 3
|
||||
Sleep 300
|
||||
MouseClick, Right ;
|
||||
Sleep 100
|
||||
MouseClick, Right
|
||||
Sleep 100
|
||||
{{ end }}
|
||||
|
||||
|
||||
; container 2 - offset 404
|
||||
{{ range .ContainerTwo }}
|
||||
row := {{ .Row }}
|
||||
col := {{ .Col }}
|
||||
MouseMove, retainerInventoryX+404+(col-1)*69, retainerInventoryY+133+(row-1)*69, 3
|
||||
Sleep 300
|
||||
MouseClick, Right ;
|
||||
Sleep 100
|
||||
MouseClick, Right
|
||||
Sleep 100
|
||||
{{ end }}
|
||||
|
||||
|
||||
; select containers 3-4
|
||||
MouseMove, retainerInventoryX+362, retainerInventoryY+68, 3
|
||||
Sleep 300
|
||||
MouseClick ; Click the 2 button to switch to containers 3-4
|
||||
MouseClick
|
||||
Sleep 20
|
||||
|
||||
; container 3 - offset 46
|
||||
{{ range .ContainerThree }}
|
||||
row := {{ .Row }}
|
||||
col := {{ .Col }}
|
||||
MouseMove, retainerInventoryX+46+(col-1)*69, retainerInventoryY+133+(row-1)*69, 3
|
||||
Sleep 300
|
||||
MouseClick, Right ;
|
||||
Sleep 100
|
||||
MouseClick, Right
|
||||
Sleep 100
|
||||
{{ end }}
|
||||
|
||||
; container 4 - offset 404
|
||||
{{ range .ContainerFour }}
|
||||
row := {{ .Row }}
|
||||
col := {{ .Col }}
|
||||
MouseMove, retainerInventoryX+404+(col-1)*69, retainerInventoryY+133+(row-1)*69, 3
|
||||
Sleep 300
|
||||
MouseClick, Right ;
|
||||
Sleep 100
|
||||
MouseClick, Right
|
||||
Sleep 100
|
||||
{{ end }}
|
||||
|
||||
; select container 5
|
||||
MouseMove, retainerInventoryX+607, retainerInventoryY+68, 3
|
||||
Sleep 300
|
||||
MouseClick ; Click the 2 button to switch to containers 3-4
|
||||
MouseClick
|
||||
Sleep 20
|
||||
|
||||
; container 5 - offset 46
|
||||
{{ range .ContainerFive }}
|
||||
row := {{ .Row }}
|
||||
col := {{ .Col }}
|
||||
MouseMove, retainerInventoryX+46+(col-1)*69, retainerInventoryY+133+(row-1)*69, 3
|
||||
Sleep 300
|
||||
MouseClick, Right ;
|
||||
Sleep 100
|
||||
MouseClick, Right
|
||||
Sleep 100
|
||||
{{ end }}
|
||||
|
||||
; Quit retainer
|
||||
Sleep 200
|
||||
Send, {Esc}
|
||||
Sleep 200
|
||||
Send, {Esc}
|
||||
Sleep 200
|
||||
Send, {Esc}
|
||||
Sleep 200
|
||||
Send, {Esc}
|
||||
Sleep 200
|
||||
Send, {Esc}
|
||||
Sleep 1000
|
||||
Click 1200, 250 ; Close dialog
|
||||
MouseClick
|
||||
Sleep 2100
|
||||
|
||||
{{ end }}
|
||||
}
|
||||
|
||||
|
||||
example() {
|
||||
MouseClick ; Click retainer
|
||||
MouseClick
|
||||
|
||||
Sleep 2500
|
||||
Click 1200, 250 ; Close dialog
|
||||
MouseClick
|
||||
Sleep 1000
|
||||
ImageSearch, outX, outY, 530, 430, 1660, 900, *150 images\sellitems.png
|
||||
if (ErrorLevel = 0) {
|
||||
MouseMove, outX+72, outY+20, 2
|
||||
Sleep 200
|
||||
MouseClick ; Click sellitems
|
||||
MouseClick
|
||||
Sleep 400
|
||||
|
||||
highestCursorY := 0 ; used to determine if we've reached the bottom of the list
|
||||
|
||||
Loop { ; loop through all items posted for sale
|
||||
|
||||
clipboard := "" ; clear the clipboard / pasted price
|
||||
|
||||
Sleep 500
|
||||
Send, {Numpad2} ; Move cursor to first/next item
|
||||
Sleep 300
|
||||
ImageSearch, outX, outY, 2050, 60, 2180, 620, *8 images\selected.png
|
||||
if (ErrorLevel = 0) {
|
||||
|
||||
; check if we have hit the bottom of the list and moved back up to the top
|
||||
if (outY < highestCursorY-15) { ; -15 to allow for tolerance in image search function
|
||||
break
|
||||
}
|
||||
|
||||
; handle case where only 1 item is posted by checking if highlighted item is near expected top of list area and it hasn't moved
|
||||
if (outY < 200) && (outY < highestCursorY+15) { ; +15 to allow for tolerance in image search function
|
||||
break
|
||||
}
|
||||
|
||||
highestCursorY = %outY% ; update highest cursory
|
||||
Send, {Numpad0} ; Select the item
|
||||
Sleep 100
|
||||
Send, {Numpad0} ; Select Adjust Price
|
||||
|
||||
|
||||
if (currentRetainer <= numNQRetainers) { ; If it's an HQ retainer, hold shift so penny pincher copies HQ price
|
||||
Send, {Shift down}
|
||||
}
|
||||
Sleep 75
|
||||
Send, {Numpad8} ; Move cursor to Compare Prices
|
||||
Sleep 85
|
||||
Send, {Numpad0} ; Select compare prices
|
||||
Sleep 850
|
||||
Send, {Esc} ; Close compare prices
|
||||
Sleep 200
|
||||
if (currentRetainer <= numNQRetainers) { ; If it's an HQ retainer, release shift
|
||||
Send, {Shift up}
|
||||
}
|
||||
|
||||
if (clipboard = "") { ; If nobody else has listed the item, just keep the same price. Also stop-gap in case dalamud / penny pincher isn't loaded correctly
|
||||
Send, {Esc} ; Close the item
|
||||
Sleep 200
|
||||
Continue ; Move on to next iteration
|
||||
}
|
||||
|
||||
ImageSearch, outX, outY, 1760, 360, 2220, 600, *150 images\askingprice.png
|
||||
if (ErrorLevel = 0) {
|
||||
MouseMove, outX+300, outY+15, 3
|
||||
Sleep 200
|
||||
MouseClick ; Click asking price input field
|
||||
Sleep 200
|
||||
SendRaw %clipboard% ; Update price
|
||||
Sleep 175
|
||||
|
||||
Send, {Enter} ; unlock cursor from numerical field
|
||||
Sleep 150
|
||||
Send, {Numpad2} ; move cursor down to confirm button
|
||||
Sleep 150
|
||||
Send, {Numpad2}
|
||||
Sleep 150
|
||||
Send, {Numpad2}
|
||||
Sleep 150
|
||||
Send, {Numpad0} ; Select confirm button
|
||||
}
|
||||
} else {
|
||||
break ; there are no items listed for sale
|
||||
}
|
||||
}
|
||||
|
||||
; Quit retainer
|
||||
Send, {Esc}
|
||||
Sleep 200
|
||||
Send, {Esc}
|
||||
Sleep 200
|
||||
Send, {Esc}
|
||||
Sleep 200
|
||||
Send, {Esc}
|
||||
Sleep 200
|
||||
Send, {Esc}
|
||||
Sleep 1000
|
||||
Click 1200, 250 ; Close dialog
|
||||
MouseClick
|
||||
Sleep 2100
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WriteLog(text) {
|
||||
FileAppend, % A_NowUTC ": " text "`n", logfile.txt ; can provide a full path to write to another directory
|
||||
}
|