Vendor

Vendor

247k Downloads

Did you change anything how to Register "external" Extensions for Vendor?

fubaWoW opened this issue ยท 5 comments

commented

Hi there,

did you change anything about how to register an external "Extension" for Vendor?
I've reactivated wow today and I use my own "Extension" for Vendor but I get this ersror:

1x Vendor/rules/extensions.lua:133: attempt to call method 'RegisterFunctions' (a nil value)
[string "@Vendor/rules/extensions.lua"]:133: in function <Vendor/rules/extensions.lua:120>
[string "@Vendor/rules/extensions.lua"]:465: in function `Register'
[string "@Vendor/rules/extensions.lua"]:514: in function <Vendor/rules/extensions.lua:513>

and this is my "Extension" for Vendor:

local AddonName, AddOn = ...

local function Vendor_HaveProfession(professionNameOrId)
	if not professionNameOrId then
		return
	end

	--local name, texture, rank, maxRank, numSpells, spellOffset, skillLine, rankModifier, specializationIndex, specializationOffset, skillLineName = GetProfessionInfo(index);
	if type(professionNameOrId) == "string" then
		local professions = {GetProfessions()}
		for _, index in next, professions do
			local name = select(1, GetProfessionInfo(index))
			local skillLineName = select(11, GetProfessionInfo(index))
			if (name == professionNameOrId) or (skillLineName == professionNameOrId) then
				return true
			end
		end
	elseif type(professionNameOrId) == "number" then
		local professions = {GetProfessions()}
		local spellName = select(1, GetSpellInfo(professionNameOrId)) -- name, rank, icon, castTime, minRange, maxRange, spellID, originalIcon = GetSpellInfo(number|string)
		for _, index in next, professions do
			local name = select(1, GetProfessionInfo(index))
			local skillLineName = select(11, GetProfessionInfo(index))
			local spellID_name = name and select(2, GetSpellLink(name)) or 0
			local spellID_skillLineName = skillLineName and select(2, GetSpellLink(skillLineName)) or 0
			if (spellID_name == professionNameOrId) or (spellID_skillLineName == professionNameOrId) then
				return true
			elseif (spellName == name) or (spellName == skillLineName) then
				return true
			end
		end
	end
	return false
end

local function registerHaveProfession()
	local HaveProfession = {
		-- Vendor will check this source is loaded prior to registration.
		-- It will also be displayed in the Vendor UI.
		Source = "fuba",
		Addon = AddonName,
		Version = 1.0,
		Functions = {
			{
				Name = "HaveProfession",
				Supported = {Retail = true, Classic = true, RetailNext = true, ClassicNext = true},
				Function = Vendor_HaveProfession,
				Help = 'Return "true" if you have learned the Profession.',
				Documentation = 'Return "true" if you have learned the Profession.'
			}
		}
	}

	-- Register this extension with Vendor.
	-- For safety, you should make sure both Vendor and the RegisterExtension method exist before
	-- calling, as done below. If not a clean LUA error will be thrown that can be reported back to players.
	assert(
		Vendor and Vendor.RegisterExtension,
		"Vendor RegisterExtension not found, cannot register extension: " .. tostring(HaveProfession.Source)
	)
	if (not Vendor.RegisterExtension(HaveProfession)) then
		-- something went wrong
		print("|cffff0000Can not Register Vendor Extesion: |r" .. HaveProfession.Addon)
	end
end
registerHaveProfession()

I've checked your "internal Extensions" like TSM or ArkInventory but the Code seems complete the same, except you now use an "internal" Function for your Rules.

Did I miss anything?!

Also the "Info Text" in the extensions.lua seems outdated:

--[[===========================================================================
    | Copyright (c) 2018
    |
    | This file defines the extension points for vendor, we allow other
    | Addon to register functions and rule definitions with vendor.
    |
    | The structure for information is as following:
    |
    |   FunctionInformation:
    |       Name = <name>
    |       Help = <help text>
    |       Function = <function>
    |
    |   Name is the name as it will be exposed to the user, it will be prefixed
    |   by the source of your extension, so if your Source is "Bar" and you
    |   register a function "Foo" the function exposed to the rules will be
    |   Bar_Foo. The help text is required, and it explains to uses how the
    |   function works.
    |
    |   RuleDefinition:
    |       Id = <id>
    |       Name = <name>
    |       Description = <description>
    |       Script = <script>
    |       Type = "Sell" | "Keep"
    |       Order = #
    |
    |   All of these fields except for Order are required and must be
    |   non-empty strings.  Order is used for sorting the definition
    |   with the custom rule list.
    |
    |   ExtensionDefinition:
    |       Rules = { RuleDefinition1...RuleDefinitionN }
    |       Functions = { FunctionDefinition1...FunctionDefinitionN }
    |       Source = <source>
    |       Addon = <addon>
    |
    |   Rules and functions are a list of the rules and definitions which
    |   should be registered.  See the details above for each of them.
    |   Source - is the name of your Vendor extension, this can whatever
    |       you desire, but anything non-alpha numeric will be turned into
    |       underscores.
    |   Addon - This is the Addon making the call, this allows vendor
    |           to get version information and track where it came from
    |           we do verify this is valid. and for the most part
    |           you can just use the result of "select(1, ...)"
    ========================================================================--]]

Maybe you can add an "Example" Extension for external Extensions so we can update them easily?

Update
Well, my "Extension" works if I integrate it into your "Internal Extension" collection (like Pawn or TSM) but not with the "RegisterExtension" as an external Extension...

I really appreciate any help you can provide.

commented

I will take a look, if this hasn't already been fixed, however that seems like a great function to just pull into our default functions, which I might do as part of 6.3

commented

2 Years later...

This file defines the extension points for vendor, we allow other
Addon to register functions and rule definitions with vendor.

The "feature" is still broken...


Just make "Addon.Systems.ExtensionManager" accessible from outside, so it's not needed to add my extension manually after each update!

like in extensionmanager.lua at the bottom just add VendorExtMgr = Addon.Systems.ExtensionManager

Or the simple way -> enable the "new" System:
https://warcraft.wiki.gg/wiki/TOC_format#AllowAddOnTableAccess
https://warcraft.wiki.gg/wiki/API_C_AddOns.GetAddOnLocalTable

just add ## AllowAddOnTableAccess: 1 in the Vendor.toc and done!

commented

Sorry this sat for so long, we just rarely look at github issues and mostly look at the discord.

I will add this to my list for Midnight release

I will NOT be adding AllowAddOnTableAccess - we very intentionally privatized our variables and expose an API. We do not want any addons mucking with how ours works and this is good programming practice and design, and that's why this broke in the first place. We refactored extension code and privatized most of the addon and forgot the external extensions. The correct solution to this is to add the ExtensionManager registration to the public API, which I'll do in a near-term update.

commented

error still not fixed!

same error:

1x Vendor/rules/extensions.lua:133: attempt to call method 'RegisterFunctions' (a nil value)
[string "@Vendor/rules/extensions.lua"]:133: in function <Vendor/rules/extensions.lua:120>
[string "@Vendor/rules/extensions.lua"]:463: in function `Register'
[string "@Vendor/rules/extensions.lua"]:512: in function <Vendor/rules/extensions.lua:511>
[string "=(tail call)"]: ?
[string "@Vendor_fubaExtensions/fubaExtensions.lua"]:91: in function `registerfubaRules'
[string "@Vendor_fubaExtensions/fubaExtensions.lua"]:98: in main chunk

Locals:
ext = <table> {
 Rules = 0
 Source = "fuba"
 Functions = 3
 OnUpdate = 0
 Name = "Vendor [6.5.0]"
}
fdef = <table> {
 Function = <function> defined @Vendor_fubaExtensions/fubaExtensions.lua:5
 Documentation = "Return "true" if you have learned the Profession.
You can use SpellName or SpellID for this function.

Example:
fuba_HaveProfession("Enchanting") will return "true" you have the "Enchanting" Profession learned.

You can also use the SpellID if you want and know it like this:
fuba_HaveProfession(7411) will also return "true" if you're an Enchanter."
 Name = "HaveProfession"
 Supported = <table> {
 }
}
f = <table> {
 Function = <function> defined @Vendor_fubaExtensions/fubaExtensions.lua:5
 SourceName = "fuba"
 Extension = <table> {
 }
 Documentation = "Return "true" if you have learned the Profession.
You can use SpellName or SpellID for this function.

Example:
fuba_HaveProfession("Enchanting") will return "true" you have the "Enchanting" Profession learned.

You can also use the SpellID if you want and know it like this:
fuba_HaveProfession(7411) will also return "true" if you're an Enchanter."
 Supported = <table> {
 }
 Name = "fuba_HaveProfession"
}
(*temporary) = nil
(*temporary) = <table> {
 MerchantButton = <table> {
 }
 c_Config_Tooltip_Rule = "tooltip_addrule"
 RuleType = <table> {
 }
 RaiseEvent = <function> defined @Vendor/sys/event.lua:124
 CopyProfile = <function> defined @Vendor/sys/profilemanager.lua:290
 DefaultConfig = <table> {
 }
 PreHookWidget = <function> defined @Vendor/sys/hook.lua:29
 c_Config_Tooltip = "tooltip_basic"
 RARE_BLUE_COLOR = <table> {
 }
 c_Config_SellThrottle = "sell_throttle"
 RuleConfig = <table> {
 }
 RemoveThread = <function> defined @Vendor/sys/thread.lua:103
 IsItemInList = <function> defined @Vendor/vendor/blocklists.lua:386
 ListToggle_Cmd = <function> defined @Vendor/cmds.lua:27
 AttachImplementation = <function> defined @Vendor/ui/dialog.lua:40
 History_Cmd = <function> defined @Vendor/features/history/history.lua:341
 TableMerge = <function> defined @Vendor/sys/helpers.lua:89
 COMMON_GRAY_COLOR = <table> {
 }
 GetProfileList = <function> defined @Vendor/sys/profilemanager.lua:230
 GetPriceString = <function> defined @Vendor/sys/systems.lua:156
 AddInitializeAction = <function> defined @Vendor/sys/core.lua:148
 c_Config_SellLimit = "autosell_limit"
 GetNumTotalEquippedBagSlots = <function> defined @Vendor/sys/systems.lua:156
 IsDebug = false
 Systems = <table> {
 }
 TableFind = <function> defined @Vendor/sys/helpers.lua:62
 CreateCategory = <function> defined @Vendor/RulesEngine/category.lua:163
 EPIC_PURPLE_COLOR = <table> {
 }
 GetCharacterFullName = <function> defined @Vendor/sys/helpers.lua:104
 RuleManager = <table> {
 }
 IsDebugChannelEnabled = <function> defined @Vendor/sys/core.lua:173
 c_Config_MerchantData = "merchantdata"
 IsConfigInitialized = <function> defined @Vendor/sys/config.lua:414
 FindDefaultProfile = <function> defined @Vendor/vendor/profileimpl.lua:130
 UnregisterFromEvents = <function> defined @Vendor/sys/systems.lua:225
 GetCurrentProfile = <function> defined @Vendor/sys/profilemanager.lua:299
 SecureHookWidget = <function> defined @Vendor/sys/hook.lua:8
 TableHasKey = <function> defined @Vendor/sys/helpers.lua:57
 ActionType = <table> {
 }
 CreateRulesEngine = <function> defined @Vendor/rules/manager.lua:44
 OnInitialize = <function> defined @Vendor/addon.lua:7
 AddConsoleCommand = <function> defined @Vendor/sys/console.lua:125
 StringRTrim = <function> defined @Vendor/sys/helpers.lua:21
 GetDebugSetting = <function> defined @Vendor/sys/core.

But it still works if i copy it directly into your internal extensions and execute it by Vendor itself!
So your Extension API is still broken, after over 1 year ^^

commented

any progress?