Add files via upload

This commit is contained in:
totalllyswede
2026-07-15 23:00:59 -07:00
committed by GitHub
commit f3e0219cc6
27 changed files with 5532 additions and 0 deletions
+281
View File
@@ -0,0 +1,281 @@
---@class GuildRecipesOcto
GuildRecipesOcto = GuildRecipesOcto or {}
---@class GuildRecipesOcto
local m = GuildRecipesOcto
---@diagnostic disable-next-line: undefined-global
local lib_stub = LibStub
GuildRecipesOcto.name = "GuildRecipes_Octo"
GuildRecipesOcto.prefix = "GROCTO"
GuildRecipesOcto.tagcolor = "FFDD7744"
GuildRecipesOcto.events = {}
GuildRecipesOcto.debug_enabled = false
GuildRecipesOcto.legacy_warning_enabled = false
BINDING_HEADER_GUILDRECIPESOCTO = "GuildRecipes Octo"
---@class Item
---@field id integer
---@field name string
---@field quality integer?
---@field icon string?
---@alias NotAceTimer any
---@alias TimerId number
---@class AceTimer
---@field ScheduleTimer fun( self: NotAceTimer, callback: function, delay: number, ... ): TimerId
---@field ScheduleRepeatingTimer fun( self: NotAceTimer, callback: function, delay: number, arg: any ): TimerId
---@field CancelTimer fun( self: NotAceTimer, timer_id: number )
---@field TimeLeft fun( self: NotAceTimer, timer_id: number )
---@class AceSerializer
---@field Serialize fun( self: any, ... ): string
---@field Deserialize fun( self: any, str: string ): any
---@class AceComm
---@field RegisterComm fun( self: any, prefix: string, method: function? )
---@field SendCommMessage fun( self: any, prefix: string, text: string, distribution: string, target: string?, prio: "BULK"|"NORMAL"|"ALERT"?, callbackFn: function?, callbackArg: any? )
function GuildRecipesOcto:init()
self.frame = CreateFrame( "Frame" )
self.frame:SetScript( "OnEvent", function()
if m.events[ event ] then
m.events[ event ]()
end
end )
for k, _ in pairs( m.events ) do
m.frame:RegisterEvent( k )
end
end
function GuildRecipesOcto.events.ADDON_LOADED()
if arg1 == m.name then
---@type AceTimer
m.ace_timer = lib_stub( "AceTimer-3.0" )
---@type AceSerializer
m.ace_serializer = lib_stub( "AceSerializer-3.0" )
---@type AceComm
m.ace_comm = lib_stub( "AceComm-3.0" )
---@type MessageHandler
m.msg = m.MessageHandler.new( m.ace_timer, m.ace_serializer, m.ace_comm )
---@type TradeskillGui
m.tsgui = m.Tradeskills.new()
---@type SlashCommand
m.slash_command = m.SlashCommand.new( m.name, { "gro", "GuildRecipesOcto" } )
m.version = GetAddOnMetadata( m.name, "Version" )
m.info( string.format( "(v%s) Loaded", m.version ) )
end
end
function GuildRecipesOcto.events.PLAYER_LOGIN()
-- Initialize DB
GuildRecipesOctoDB = GuildRecipesOctoDB or {}
m.db = GuildRecipesOctoDB
m.db.players = m.db.players or {}
m.db.tradeskills = m.db.tradeskills or {}
m.db.tradeskills_last_update = m.db.tradeskills_last_update or {}
m.db.frame_tradeskills = m.db.frame_tradeskills or {}
m.player = UnitName( "player" )
m.player_class = UnitClass( "player" )
if m.slash_command then
m.slash_command.init()
end
m.tooltip = CreateFrame( "GameTooltip", "GuildRecipesOctoTooltip", nil, "GameTooltipTemplate" )
m.tooltip:SetOwner( WorldFrame, "ANCHOR_NONE" )
if m.msg then
m.update_data()
end
end
function GuildRecipesOcto.events.TRADE_SKILL_SHOW()
local reverse = m.build_reverse_trade_map( GetLocale() )
local tradeskill = reverse[ GetTradeSkillLine() ]
if m.TRADE_SKILL_LOCALIZATION[ tradeskill ] then
local num = GetNumTradeSkills()
for i = 1, GetNumTradeSkills() do
local _, type = GetTradeSkillInfo( i )
if type == "header" then
num = num - 1
end
end
m.db.tradeskills[ tradeskill ] = m.db.tradeskills[ tradeskill ] or {}
if m.count_recipes( m.db.tradeskills[ tradeskill ], m.player ) ~= num then
for i = 1, GetNumTradeSkills() do
local _, type = GetTradeSkillInfo( i )
if type ~= "header" then
local id, name, quality = m.parse_item_link( GetTradeSkillItemLink( i ) )
local item = {
id = id,
name = name,
quality = quality
}
m.update_tradeskill_item( tradeskill, item, { m.player } )
end
end
m.db.tradeskills_last_update[ tradeskill ] = m.get_server_timestamp()
m.msg.send_tradeskill( tradeskill )
end
end
end
function GuildRecipesOcto.events.CRAFT_SHOW()
local reverse = m.build_reverse_trade_map( GetLocale() )
local tradeskill = reverse[ GetCraftName() ]
if tradeskill == "Enchanting" then
local num = GetNumCrafts()
m.db.tradeskills[ tradeskill ] = m.db.tradeskills[ tradeskill ] or {}
if m.count_recipes( m.db.tradeskills[ tradeskill ], m.player ) ~= num then
for i = 1, num do
local id, name, quality = m.parse_item_link( GetCraftItemLink( i ) )
local item = {
id = id,
name = name,
quality = quality
}
m.update_tradeskill_item( tradeskill, item, { m.player } )
end
m.db.tradeskills_last_update[ tradeskill ] = m.get_server_timestamp()
m.msg.send_tradeskill( tradeskill )
end
end
end
function GuildRecipesOcto.events.UNIT_INVENTORY_CHANGED()
-- This can fire many times in quick succession (e.g. once per item when
-- looting a stack), and each call to tsgui.update() re-scans the guild
-- roster and redraws the visible list. Debounce so a burst of these only
-- triggers one actual update, instead of one per event.
if arg1 == "player" and m.tsgui.is_visible() and m.ace_timer then
if m.inventory_update_timer then
m.ace_timer.CancelTimer( m, m.inventory_update_timer )
end
m.inventory_update_timer = m.ace_timer.ScheduleTimer( m, function()
m.inventory_update_timer = nil
if m.tsgui.is_visible() then
m.tsgui.update()
end
end, 0.5 )
end
end
---@param tradeskill string
---@param item Item
---@param players string[]
function GuildRecipesOcto.update_tradeskill_item( tradeskill, item, players )
if item.id then
local player_ids = {}
for _, p in pairs( players ) do
if not m.find( p, m.db.players ) then
table.insert( m.db.players, p )
end
local _, player_id = m.find( p, m.db.players )
if player_id then
table.insert( player_ids, player_id )
end
end
if m.db.tradeskills[ tradeskill ][ item.id ] then
m.debug( string.format( "Updating %s: %s", tradeskill, item.name ) )
if not players then
m.debug( "ERROR, no players for: " .. tostring( item.name ) )
return
end
local recipe_players = m.comma_separated_to_table( m.db.tradeskills[ tradeskill ][ item.id ].p )
for _, p in pairs( players ) do
local _, player_id = m.find( p, m.db.players )
if player_id and not m.find( tostring(player_id), recipe_players ) then
table.insert( recipe_players, player_id )
end
end
m.db.tradeskills[ tradeskill ][ item.id ].p = m.table_to_comma_separated( recipe_players )
else
m.debug( string.format( "Adding %s: %s", tradeskill, item.name ) )
m.db.tradeskills[ tradeskill ][ item.id ] = {
n = item.name,
q = item.quality,
p = m.table_to_comma_separated( player_ids )
}
end
end
end
function GuildRecipesOcto.update_data()
-- If we haven't updated in the last 48 hours, request an update
if next(m.db.tradeskills_last_update) == nil then
m.msg.request_tradeskills()
else
local now = m.get_server_timestamp()
for tradeskill, last_update in pairs( m.db.tradeskills_last_update ) do
if now >= last_update + 172800 then
m.msg.request_tradeskill( tradeskill )
break
end
end
end
end
---@param bag_start integer
---@param bag_end integer
---@param name string
---@return integer
function GuildRecipesOcto.find_item_count_bag( bag_start, bag_end, name )
local count = 0
for bag = bag_start, bag_end do
local slots = GetContainerNumSlots( bag )
for slot = 1, slots do
local _, item_count = GetContainerItemInfo( bag, slot )
if item_count and item_count > 0 then
local _, item_name = m.parse_item_link( GetContainerItemLink( bag, slot ) )
if item_name == name then
count = count + item_count
end
end
end
end
return count
end
function GuildRecipesOcto.fix()
for tradeskill, recipes in pairs( m.db.tradeskills ) do
for id, recipe in pairs( recipes ) do
if recipe.p and type( recipe.p ) == "table" then
local players = ""
for _, p in pairs( recipe.p ) do
if players ~= "" then
players = players .. ","
end
players = players .. p
end
recipe.p = players
end
end
end
end
GuildRecipesOcto:init()