Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 48 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,55 @@ on:
branches: [ dev ]
workflow_dispatch:
jobs:
lint:
runs-on: ubuntu-latest
container: ghcr.io/musholic/lastepochplanner-tests:latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Download LuaLS Addons
run: |
git clone --depth 1 https://github.com/LuaLS/LLS-Addons.git .lls-addons
cd .lls-addons
git submodule update --init --depth 1 addons/busted
git submodule update --init --depth 1 addons/luassert
git submodule update --init --depth 1 addons/luafilesystem

- name: Patch .luarc.json for CI + clean up
run: |
sed -i 's|${addons}|.lls-addons/addons|g' .luarc.json
# Delete the Lua 5.3 specific file so it doesn't break LuaJIT parsing
rm -f runtime/lua/sha1/lua53_ops.lua
# Delete the ModCache which slows down type checking
rm -f src/Data/ModCache.lua
- name: Type Check Code Base
run: lua-language-server --check . --check_format=json --logpath=.
- name: Annotate GitHub PR from check.json
if: always()
run: |
LOG_FILE="check.json"
if [ -f "$LOG_FILE" ]; then
cat $LOG_FILE | jq -r --arg ws "$GITHUB_WORKSPACE" '
to_entries[] |
# 1. Strip "file://..." prefix and convert to relative path
(.key | sub("file://"; "") | ltrimstr($ws) | ltrimstr("/")) as $file |

# 2. Iterate over issues
.value[] |
# 3. Map LSP severity (1:Error, 2:Warning) to GH format
(if .severity == 1 then "error" else "warning" end) as $sev |

# 4. Convert 0-indexed LSP (line 55, char 0) to 1-indexed GH (line 56, col 1)
# GitHub requires line and col. Optional: endLine, endColumn
"::\($sev) file=\($file),line=\(.range.start.line + 1),col=\(.range.start.character + 1),endLine=\(.range.end.line + 1),endColumn=\(.range.end.character + 1)::\($file): \(.message) (code: \(.code))"
'
else
echo "::warning::check.json not found, skipping annotations."
fi
run_tests:
runs-on: ubuntu-latest
container: ghcr.io/pathofbuildingcommunity/pathofbuilding-tests:latest
container: ghcr.io/musholic/lastepochplanner-tests:latest
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -19,7 +65,7 @@ jobs:
run: cd src; luacov-coveralls --repo-token=${{ secrets.github_token }} -e TestData -e Data -e runtime
check_modcache:
runs-on: ubuntu-latest
container: ghcr.io/pathofbuildingcommunity/pathofbuilding-tests:latest
container: ghcr.io/musholic/lastepochplanner-tests:latest
steps:
- name: Install git dependency
run: apk add git
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ src/Export/ggpk/*.dll
src/TreeData/**/*.scm
src/TreeData/**/*.txt
src/TreeData/**/*.bat

# PoB Trader
*_currency_values.json

Expand Down
37 changes: 37 additions & 0 deletions .luarc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"runtime": {
"version": "LuaJIT"
},
"workspace": {
"library": [
"runtime/lua",
"${addons}/busted/module/library",
"${addons}/luassert/module/library",
"${addons}/luafilesystem/module/library"
],
"ignoreDir": ["runtime", "src/Export"]
},
"diagnostics": {
"globals": ["UpdateProgress"],
"severity": {
"need-check-nil": "Information",
"param-type-mismatch": "Information",
"undefined-field": "Information",
"undefined-doc-class": "Information",
"undefined-doc-name": "Information",
"missing-return": "Information",
"inject-field": "Information",
"assign-type-mismatch": "Information",
"cast-local-type": "Information"
},
"disable": ["lowercase-global"]
},
"hint": {
"enable": true
},
"Lua.format.defaultConfig": {
"indent_style": "tab",
"indent_size": "4"
},
"workspace.checkThirdParty": false
}
7 changes: 5 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM alpine:3.18 AS base
FROM alpine:3.22 AS base
# Common dependencies
RUN apk add --no-cache cmake readline-dev build-base tar

Expand All @@ -18,13 +18,16 @@ RUN git clone https://github.com/LuaJIT/LuaJIT && cd LuaJIT && git checkout 871d
RUN cd LuaJIT && make

FROM buildbase AS emmyluadebugger
RUN git clone --depth 1 --branch 1.7.1 https://github.com/EmmyLua/EmmyLuaDebugger
RUN git clone --depth 1 --branch 1.8.7 https://github.com/EmmyLua/EmmyLuaDebugger
RUN cd EmmyLuaDebugger && mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release ../ && make

FROM base
# Luarocks packages dependencies
RUN apk add --no-cache curl unzip openssl

# Install other dependencies useful for the CI
RUN apk add --no-cache libxml2-utils git lua-language-server jq

RUN --mount=type=cache,from=buildBase,source=/opt,target=/opt make -C /opt/lua-5.1.5/ install
RUN --mount=type=cache,from=luarocks,source=/opt,target=/opt make -C /opt/luarocks-3.7.0/ install

Expand Down
3 changes: 2 additions & 1 deletion spec/System/TestTradeQueryRequests_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ describe("TradeQueryRequests", function()
it("retries on 429 with exponential backoff", function()
local orig_os_time = os.time
local mock_time = 1000
---@diagnostic disable-next-line: duplicate-set-field
os.time = function() return mock_time end

local request = {
Expand Down Expand Up @@ -192,4 +193,4 @@ describe("TradeQueryRequests", function()
requests.FetchResultBlock = orig_fetchBlock
end)
end)
end)
end)
4 changes: 2 additions & 2 deletions src/Classes/CalcsTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ Effective DPS: Curses and enemy properties (such as resistances and status condi
self.powerBuilderInitialized = nil
end)

function CalcsTabClass:Load(xml, dbFileName)
function CalcsTabClass:Load(xml, fileName)
for _, node in ipairs(xml) do
if type(node) == "table" then
if node.elem == "Input" then
Expand Down Expand Up @@ -631,7 +631,7 @@ function CalcsTabClass:PowerBuilder()

-- Calculate the impact of every cluster notable
-- used for the power report screen
for nodeName, node in pairs(self.build.spec.tree.clusterNodeMap) do
for nodeId, node in pairs(self.build.spec.tree.clusterNodeMap) do
if not node.power then
node.power = {}
end
Expand Down
2 changes: 1 addition & 1 deletion src/Classes/ControlHost.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function ControlHostClass:ProcessControlsInput(inputEvents, viewPort)
inputEvents[id] = nil
end

local mOverControl = self:GetMouseOverControl(viewPort)
local mOverControl = self:GetMouseOverControl()

-- Avoid calculating isMouseInRegion as much as possible as it's expensive
if mOverControl and (not selControl or mOverControl.OnHoverKeyUp) then
Expand Down
2 changes: 1 addition & 1 deletion src/Classes/EditControl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ function EditClass:Draw(viewPort, noTooltip)
else
SetDrawColor(self.inactiveCol)
if self.inactiveText then
local inactiveText = type(inactiveText) == "string" and self.inactiveText or self.inactiveText(self.buf)
local inactiveText = type(self.inactiveText) == "string" and self.inactiveText or self.inactiveText(self.buf)
DrawString(-self.controls.scrollBarH.offset, -self.controls.scrollBarV.offset, "LEFT", textHeight, self.font, inactiveText)
elseif self.protected then
DrawString(-self.controls.scrollBarH.offset, -self.controls.scrollBarV.offset, "LEFT", textHeight, self.font, string.rep(protected_replace, #self.buf))
Expand Down
6 changes: 3 additions & 3 deletions src/Classes/GemSelectControl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ function GemSelectClass:UpdateSortCache()
sortCache.dps[gemId] = baseDPS
-- Ignore gems that don't support the active skill
if sortCache.canSupport[gemId] or (gemData.grantedEffect.hasGlobalEffect and not gemData.grantedEffect.support) then
local output = self:CalcOutputWithThisGem(calcFunc, gemData, useFullDPS, fastCalcOptions, calcBase)
local output = self:CalcOutputWithThisGem(calcFunc, gemData, useFullDPS)
-- Check for nil because some fields may not be populated, default to 0
sortCache.dps[gemId] = (dpsField == "FullDPS" and output[dpsField] ~= nil and output[dpsField]) or (output.Minion and output.Minion.CombinedDPS) or (output[dpsField] ~= nil and output[dpsField]) or 0
end
Expand Down Expand Up @@ -452,7 +452,7 @@ function GemSelectClass:Draw(viewPort, noTooltip)
if calcFunc then
self.tooltip:Clear()
local gemData = self.gems[self.list[self.hoverSel]]
local output = self:CalcOutputWithThisGem(calcFunc, gemData, self.skillsTab.sortGemsByDPSField == "FullDPS", nil, calcBase)
local output = self:CalcOutputWithThisGem(calcFunc, gemData, self.skillsTab.sortGemsByDPSField == "FullDPS")
local gemInstance = {
level = self.skillsTab:ProcessGemLevel(gemData),
quality = self.skillsTab.defaultGemQuality or 0,
Expand Down Expand Up @@ -911,4 +911,4 @@ function GemSelectClass:OnKeyUp(key)
end
local newSel = self.EditControl:OnKeyUp(key)
return newSel == self.EditControl and self or newSel
end
end
1 change: 1 addition & 0 deletions src/Classes/ImportTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,7 @@ function ImportTabClass:ImportItemsAndSkills(charData)
elseif not orderA and not orderB then
return groupOrder[a] < groupOrder[b]
else
---@diagnostic disable-next-line: return-type-mismatch
return orderA
end
end)
Expand Down
2 changes: 1 addition & 1 deletion src/Classes/ItemsTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2163,7 +2163,7 @@ end

---Gets the name of the anointed node on an item
---@param item table @The item to get the anoint from
---@return string @The name of the anointed node, or nil if there is no anoint
---@return table? @The names of the anointed node, or nil if there is no anoint
function ItemsTabClass:getAnoint(item)
local result = { }
if item then
Expand Down
4 changes: 2 additions & 2 deletions src/Classes/ModDB.lua
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ function ModDBClass:ListInternal(context, result, cfg, flags, keywordFlags, sour
if mod.type == "LIST" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.source:match("[^:]+") == source) then
local value
if mod[1] then
local value = context:EvalMod(mod, cfg) or nullValue
local value = context:EvalMod(mod, cfg) or nil
if value then
t_insert(result, value)
end
Expand Down Expand Up @@ -315,4 +315,4 @@ function ModDBClass:Print()
for i, name in ipairs(nameList) do
ConPrintf("%s = %d", name, self.multipliers[name])
end
end
end
2 changes: 1 addition & 1 deletion src/Classes/ModList.lua
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ function ModListClass:ListInternal(context, result, cfg, flags, keywordFlags, so
if mod.name == modName and mod.type == "LIST" and band(flags, mod.flags) == mod.flags and MatchKeywordFlags(keywordFlags, mod.keywordFlags) and (not source or mod.source:match("[^:]+") == source) then
local value
if mod[1] then
local value = context:EvalMod(mod, cfg) or nullValue
local value = context:EvalMod(mod, cfg) or nil
if value then
t_insert(result, value)
end
Expand Down
3 changes: 2 additions & 1 deletion src/Classes/ModStore.lua
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ function ModStoreClass:GetStat(stat, cfg)
local totalLife = self.actor.output["Life"]
if totalLife == 0 then return 0 else
for _, activeSkill in ipairs(self.actor.activeSkillList) do
---@diagnostic disable-next-line: undefined-global
if (activeSkill.skillTypes[SkillType.HasReservation] and not activeSkill.skillFlags.disable and activeSkill.buffList and activeSkill.buffList[1] and cfg and (isNameInBuffList(activeSkill.buffList, cfg.skillName) or isNameInBuffList(activeSkill.buffList, cfg.summonSkillName)) ) then
local lifeBase = activeSkill.skillData["LifeReservedBase"] or 0
reservedPercentLife = lifeBase / totalLife * 100
Expand Down Expand Up @@ -863,4 +864,4 @@ function ModStoreClass:EvalMod(mod, cfg, globalLimits)
end
end
return value
end
end
5 changes: 4 additions & 1 deletion src/Classes/PartyTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,11 @@ local PartyTabClass = newClass("PartyTab", "ControlHost", "Control", function(se
-- Parse the XML
local dbXML, errMsg = common.xml.ParseXML(self.importCodeXML)
if not dbXML then
---@diagnostic disable-next-line: undefined-global
launch:ShowErrMsg("^1Error loading '%s': %s", fileName, errMsg)
return
elseif dbXML[1].elem ~= "PathOfBuilding2" then
---@diagnostic disable-next-line: undefined-global
launch:ShowErrMsg("^1Error parsing '%s': 'PathOfBuilding2' root element missing", fileName)
return
end
Expand Down Expand Up @@ -908,6 +910,7 @@ function PartyTabClass:ParseBuffs(list, buf, buffType, label)
end
end
if list["AuraDebuff"] and list["AuraDebuff"]["Vaal"] then
---@diagnostic disable-next-line: undefined-global
if not list["Aura"] or not list["Aura"]["Vaal"] or not list["Aura"]["Vaal"][aura] then
for aura, auraMod in pairs(list["AuraDebuff"]["Vaal"]) do
t_insert(labelList, aura..": "..auraMod.effectMult.."%\n")
Expand Down Expand Up @@ -1032,4 +1035,4 @@ function PartyTabClass:exportBuffs(buffType)
self.buffExports[buffType] = { ConvertedToText = true }
self.buffExports[buffType].string = buf
return buf
end
end
2 changes: 1 addition & 1 deletion src/Classes/PassiveSpec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2255,7 +2255,7 @@ end
--- Adds a line to or replaces a node given a line to add/replace with
--- @param node table The node to replace/add to
--- @param sd string The line being parsed and added
--- @param replacement boolean true to replace the node with the new mod, false to simply add it
--- @param replacement boolean? true to replace the node with the new mod, false to simply add it
function PassiveSpecClass:NodeAdditionOrReplacementFromString(node,sd,replacement)
local addition = {}
addition.sd = {sd}
Expand Down
2 changes: 1 addition & 1 deletion src/Classes/ResizableEditControl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ local ResizableEditClass = newClass("ResizableEditControl", "EditControl", funct
self.protected = false
end)
function ResizableEditClass:Draw(viewPort, noTooltip)
self:SetBoundedDrag(self)
self:SetBoundedDrag()
self.EditControl:Draw(viewPort, noTooltip)
end
function ResizableEditClass:SetBoundedDrag()
Expand Down
4 changes: 2 additions & 2 deletions src/Classes/SkillsTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1035,7 +1035,7 @@ function SkillsTabClass:ProcessSocketGroup(socketGroup)
gemInstance.color = "^8"
gemInstance.nameSpec = gemInstance.nameSpec or ""
local prevDefaultLevel = gemInstance.gemData and gemInstance.gemData.naturalMaxLevel or (gemInstance.new and 20)
gemInstance.gemData, gemInstance.grantedEffect = nil
gemInstance.gemData, gemInstance.grantedEffect = nil, nil
if gemInstance.gemId then
-- Specified by gem ID
-- Used for skills granted by skill gems
Expand Down Expand Up @@ -1074,7 +1074,7 @@ function SkillsTabClass:ProcessSocketGroup(socketGroup)
gemInstance.nameSpec = gemInstance.gemData.name
end
else
gemInstance.errMsg, gemInstance.gemData, gemInstance.skillId = nil
gemInstance.errMsg, gemInstance.gemData, gemInstance.skillId = nil, nil, nil
end
if gemInstance.gemData and gemInstance.gemData.grantedEffect.unsupported then
gemInstance.errMsg = gemInstance.nameSpec .. " is not supported yet"
Expand Down
8 changes: 5 additions & 3 deletions src/Classes/TradeQuery.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ local TradeQueryClass = newClass("TradeQuery", function(self, itemsTab)
end)

---Fetch currency short-names from Poe API (used for PoeNinja price pairing)
---@param callback fun()
---@param callback fun(data, errMsg)
function TradeQueryClass:FetchCurrencyConversionTable(callback)
launch:DownloadPage(
"https://www.pathofexile.com/api/trade2/data/static",
Expand Down Expand Up @@ -94,7 +94,8 @@ function TradeQueryClass:PullLeagueList()
self.hostName .. "api/leagues?type=main&compact=1",
function(response, errMsg)
if errMsg then
self:SetNotice(self.controls.pbNotice, "Error: " .. tostring(errMsg))
self:SetNotice(self.controls.pbNotice, "Error: " .. tostring(errMsg))
---@diagnostic disable-next-line: redundant-return-value
return "POE ERROR", "Error: "..errMsg
else
local json_data = dkjson.decode(response.body)
Expand Down Expand Up @@ -168,7 +169,7 @@ function TradeQueryClass:PullPoENinjaCurrencyConversion(league)
self:SetNotice(self.controls.pbNotice, "Failed to Get PoE Ninja response")
return
end
self:PriceBuilderProcessPoENinjaResponse(json_data, self.controls)
self:PriceBuilderProcessPoENinjaResponse(json_data)
local print_str = ""
for key, value in pairs(self.pbCurrencyConversion[self.pbLeague]) do
print_str = print_str .. '"'..key..'": '..tostring(value)..','
Expand Down Expand Up @@ -545,6 +546,7 @@ function TradeQueryClass:SetStatWeights(previousSelectionList)
local sliderOffsetX = round(184 * (1 - controls.Slider.val))
local tooltipWidth, tooltipHeight = self:GetSize()
if main.screenW >= 1338 - sliderOffsetX then
---@diagnostic disable-next-line: undefined-global
return controls[stat.label.."Slider"].tooltip.realDraw(self, x - 8 - sliderOffsetX, y - 4 - tooltipHeight, width, height, viewPort)
end
return controls.Slider.tooltip.realDraw(self, x, y, width, height, viewPort)
Expand Down
Loading
Loading