ESOUI

ESOUI (https://www.esoui.com/forums/index.php)
-   Lua/XML Help (https://www.esoui.com/forums/forumdisplay.php?f=175)
-   -   Manipulate the Chat (https://www.esoui.com/forums/showthread.php?t=4639)

stAjora 04/23/15 07:25 PM

Manipulate the Chat
 
I'm looking at the chat functions and I was wondering what the extra chat channels are for and how do you access/use them? http://wiki.esoui.com/Globals#MsgChannelType
CHAT_CHANNEL_USER_CHANNEL_1
CHAT_CHANNEL_USER_CHANNEL_2
CHAT_CHANNEL_USER_CHANNEL_3
etc

Is there a way for an add on to BLOCK a message from appearing? (I know there is probably a in game IGNORE) but for design purposes, what would blocking a message from a particular player look like in an add on?

Ayantir 04/23/15 07:59 PM

They're for GM's when they talk to you (sometimes).
You cannot use them, because nobody listens on them.. except gm's.
And no, you can't use them to send messages, because we can't "join" "users channels".

--

If you want to block messages, you can use a library that I wrote, libChat2

Here you can register library with the parameter you're interested in.

ex :
Lua Code:
  1. -- Registering librairies
  2. local LC = LibStub('libChat-1.0')
  3. LC:registerName(deleteifnotafriend, "myAddon")
  4.  
  5. local function deleteifnotafriend(channelId, from)
  6.  
  7.     -- will delete all messages wich don't come from a friend
  8.     if (not IsFriend()) return false end
  9.    
  10.    -- if friend, just return from
  11.    return from
  12.  
  13. end

stAjora 04/23/15 09:16 PM

Your pChat add on is amazing!!

Also, thanks for the information!

stAjora 04/23/15 09:58 PM

Why do the CHAT_SYSTEM functions not work? I can get CHAT_SYSTEM:AddMessage() to work but things like CHAT_SYSTEM:Clear() and CHAT_SYSTEM:GetMaxHistoryLines() throw an error.

Also, I thought I was crazy but am I right in that there are a **** ton of functions, specifically ZO_ functions that have no documentation? I'm finding threads and a bunch of code using or referencing these functions but I have no idea how people are figuring out how to use them.

Ayantir 04/23/15 11:23 PM

CHAT_SYSTEM:Clear() doesn't exists. :GetMaxHistoryLines() neither.


And yes, 99% of ZO functions are undocumented, each addon author after some releases get it's own expertise on its domain of coding, so we do like that, it's maybe not really good but making docs is not the favorite task of an unpaid developper.

Sasky 04/24/15 09:56 AM

Quote:

Originally Posted by stAjora (Post 20821)
I'm finding threads and a bunch of code using or referencing these functions but I have no idea how people are figuring out how to use them.

In some cases, it's looking at the source code[1]. There's a bit more documentation there, though some is just reading the code to see what it does. Or searching the source for the function to see how it's used. I've done that in particular to get something tightly integrated in the standard UI.

One thing to keep in mind is some of the stuff people utilize isn't so much API anymore as hooking into the ingame UI code. The main difference is (theoretically) using the API would be more stable and less likely to break.

[1] - Online at http://esodata.uesp.net/current/src/luadir.html . Also some links to ZIPs on these forums.

stAjora 04/24/15 01:16 PM

Quote:

Originally Posted by Ayantir (Post 20816)
They're for GM's when they talk to you (sometimes).
You cannot use them, because nobody listens on them.. except gm's.
And no, you can't use them to send messages, because we can't "join" "users channels".

--

If you want to block messages, you can use a library that I wrote, libChat2

Here you can register library with the parameter you're interested in.

ex :
Lua Code:
  1. -- Registering librairies
  2. local LC = LibStub('libChat-1.0')
  3. LC:registerName(deleteifnotafriend, "myAddon")
  4.  
  5. local function deleteifnotafriend(channelId, from)
  6.  
  7.     -- will delete all messages wich don't come from a friend
  8.     if (not IsFriend()) return false end
  9.    
  10.    -- if friend, just return from
  11.    return from
  12.  
  13. end


I got the library and example function registered and working but how do I specify that the effect should only take place in one type of chat window /zone /say /guild etc. ? Currently (the block function example) works for every chat window. What I'm trying to do is detect certain words in a /whisper message and stop them from being displayed.

stAjora 04/24/15 01:19 PM

Quote:

Originally Posted by Sasky (Post 20829)
In some cases, it's looking at the source code[1]. There's a bit more documentation there, though some is just reading the code to see what it does. Or searching the source for the function to see how it's used. I've done that in particular to get something tightly integrated in the standard UI.

One thing to keep in mind is some of the stuff people utilize isn't so much API anymore as hooking into the ingame UI code. The main difference is (theoretically) using the API would be more stable and less likely to break.

[1] - Online at http://esodata.uesp.net/current/src/luadir.html . Also some links to ZIPs on these forums.

Oh so ZO_ functions aren't even part of the API but functions that actually do **** with the actual game and people are just stealing them and using them in their add ons?

Ayantir 04/24/15 03:57 PM

yes we do.

circonian 04/25/15 08:11 PM

Quote:

Originally Posted by stAjora (Post 20821)
Why do the CHAT_SYSTEM functions not work? I can get CHAT_SYSTEM:AddMessage() to work but things like CHAT_SYSTEM:Clear() and CHAT_SYSTEM:GetMaxHistoryLines() throw an error.

Also, I thought I was crazy but am I right in that there are a **** ton of functions, specifically ZO_ functions that have no documentation? I'm finding threads and a bunch of code using or referencing these functions but I have no idea how people are figuring out how to use them.

As Ayantir said those don't exist. I think what you wanted was:
Lua Code:
  1. CHAT_SYSTEM.primaryContainer.currentBuffer:Clear()
  2. CHAT_SYSTEM.primaryContainer.currentBuffer:GetMaxHistoryLines()

As for the functions, like they said we find them by reading the games lua files or using /zgoo.
This addon has a feature to search the games global table for global functions. I use it to find functions I might want to use or to just look up a function when I forget its name. As for figuring out how to use the function, once I find a function that sounds like what I want then I go to the lua files and search for it to see how they use it, what the parameters are, and what values it returns if any. Click4Info

stAjora 04/25/15 10:46 PM

Quote:

Originally Posted by circonian (Post 20857)
As Ayantir said those don't exist. I think what you wanted was:
Lua Code:
  1. CHAT_SYSTEM.primaryContainer.currentBuffer:Clear()
  2. CHAT_SYSTEM.primaryContainer.currentBuffer:GetMaxHistoryLines()

As for the functions, like they said we find them by reading the games lua files or using /zgoo.
This addon has a feature to search the games global table for global functions. I use it to find functions I might want to use or to just look up a function when I forget its name. As for figuring out how to use the function, once I find a function that sounds like what I want then I go to the lua files and search for it to see how they use it, what the parameters are, and what values it returns if any. Click4Info


You're right those are what I was looking for but from the documentation (or rather the list of functions) I couldn't tell that I needed to dig down to currentBuffer. I loaded up zgoo and my god, I don't see how you can derive anything from that. I did /zgoo mouse over the chat window and I see the currentBuffer and the methods under it but I still am at a loss. I was reading through the source to pchat and X4D_CHAT and I still can't make heads or tails of what's going on in them. My coding skills must be hella weak... When you say you 'go to the lua files and search for it', if you meant the ESO client where are those stored? Mine might be different since I'm using the beta client.

circonian 04/25/15 11:55 PM

Quote:

Originally Posted by stAjora (Post 20866)
When you say you 'go to the lua files and search for it', if you meant the ESO client where are those stored? Mine might be different since I'm using the beta client.

Ayantir has posted a copy of the files, you can find them here: 2.0.4
It is near the top, look for the link: ESOUI 2.0.4 CURRENT Live
It is a link to a zip file that contains the lua files for the game.


Quote:

Originally Posted by stAjora (Post 20866)
You're right those are what I was looking for but from the documentation (or rather the list of functions) I couldn't tell that I needed to dig down to currentBuffer.

Yeah, to be honest I'm not sure of the "correct" way to say this, my terminology may not be accurate, maybe someone else could explain it better, but this should hopefully give you an idea of whats going on.

That list of functions you were looking at on the wiki API page are global functions that reside directly in the main area of the global table (not inside of another table). You can call them directly without needing to have any other object.

No other function in the same "area/table" can have the same name.
I think of them like addresses to a location, no two objects (variables, functions, tables, exc..) can have the same address:
When I repeatedly use the word objects below, if it helps to understand, they are all tables in this example.
Lua Code:
  1. -- Everything resides in the global table, nothing exists outside of it:
  2. globalTable = {
  3. -- This is directly in the global table
  4. -- These are the funcitons listed one the wiki API page:
  5.    Clear = ...,
  6. -- We can't have another Clear function here, it would just overwrite the first one
  7. -- because its in the same table as the one above (directly in the main table)
  8.    Clear = ...,
  9.  
  10. -- but we could do this:
  11.    CHAT_SYSTEM = {
  12.       primaryContainer = {
  13.          currentBuffer = {
  14. -- Because this one, although technically is still inside of the global table
  15. -- is also inside of the CHAT_SYSTEM, primaryContainer, & currentBuffer
  16. -- tables...it has a different address/location
  17.             Clear = ...,
  18.          ...
  19.          },
  20.       ...
  21.       },
  22.    ...
  23.    },
  24. }

In order to clear the chat buffer, you have to have the currentBuffer object and you call "it's" Clear() function, which is contained in the buffer object.
If you just called Clear() the game would look for it directly in the global table and if found it would call that one, but it would NOT look inside of any other tables so it would not see the one inside of the CHAT_SYSTEM.primaryContainer.currentBuffer table.
If we want to call that clear function we need to...give it that address/location so it knows which Clear() function we are wanting to call.

Using:
Lua Code:
  1. CHAT_SYSTEM.primaryContainer.currentBuffer:Clear()
Which basically says, go into the CHAT_SYSTEM object and get the object called primaryContainer, then inside of that get the currentBuffer object , then call the Clear() function that is inside that currentBuffer object.

So in short it tells the game to call the Clear() function that belongs to the CHAT_SYSTEM.primaryContainer.currentBuffer object. It also passes that current buffer object to the Clear() function as the first parameter (thats what the : means before the function name).


Quote:

Originally Posted by stAjora (Post 20866)
I loaded up zgoo and my god, I don't see how you can derive anything from that. I did /zgoo mouse over the chat window and I see the currentBuffer and the methods under it but I still am at a loss.

Basically it comes down to understanding the structure that I just..."attempted" to poorly explain above.
When you do /zgoo mouse it just shows all of the tables that belong to the "object" you had your mouse over, often with more & more tables nested inside of it. You just have to search around and try to find what your looking for sometimes.

stAjora 04/27/15 01:05 PM

I read up on Lua's scoping and I'm pretty sure I understand it. I see the function that allowed us to send chat messages is now protected, is that what all the bot spammers were using? It kind of seems silly to block it, writing a spam bot to send keypresses to the client as a 3rd party tool is still an option.

I'm currently reading through sharedchatsystem.lua, thanks for linking me to the files. I'm trying to figure out how to read the contents of the chat buffer so I can look for specific strings but I'm not seeing where its stored or how to access it.

Can someone explain what the "..." us all about? I'm seeing it a lot, mostly as new(...). Also "#", what does this do?

Ayantir 04/27/15 02:16 PM

There are no function to get a textbuffer content

# mean sizeof(variable) , var must be an array. It's non recursive

if
Lua Code:
  1. local myarray = {1,2,3}

#myarray will be 3


(...) means arguments inherited from.

ex :

Lua Code:
  1. function mother(arg1, arg2, arg3)
  2.     daughter(arg1, arg2, arg3)
  3. end
  4.  
  5. function father(anotherarg)
  6.     daughter(anotherarg)
  7. end
  8.  
  9. function daughter(...)
  10.   -- do stuff
  11. end
here ... will be arg1, arg2, arg3 when called from mother, it will be anotherarg when called from father.




Quote:

I see the function that allowed us to send chat messages is now protected, is that what all the bot spammers were using?
Not really.

Quote:

I'm trying to figure out how to read the contents of the chat buffer so I can look for specific strings but I'm not seeing where its stored or how to access it.
You need to listen to

Lua Code:
  1. EVENT_CHAT_MESSAGE_CHANNEL (integer eventCode, integer messageType, string fromName, string text, bool isCustomerService)

You can't read chat buffer, you need to catch them when messages comes.

Baertram 04/27/15 04:01 PM

Quote:

Originally Posted by Ayantir (Post 20926)
You can't read chat buffer, you need to catch them when messages comes.


Lua Code:
  1. --Put this somewhere above and outside the player activated event callback function
  2. local function myChatMessageChannelCallbackFunction(eventCode, messageType, fromName, text)
  3.    if messageType = CHAT_CHANNEL_GUILD1 then
  4.       d("Guild channel 1 message received from " .. fromName .. ": " .. text)
  5.    end
  6.  
  7.    --return false = run the other event callback functions for the same event
  8.    --return true = don#t run the other event callback functions for this event as you tell them by "true":    Everything was done already in this function here
  9.    --The same applies to ZoPreHook() and ZoPreHookHandler() functions
  10.     return false
  11. end
  12.  
  13. --Put this into player activated event callback function
  14. --Register the event for new text messages to check incoming texts at all the chat channels
  15. EVENT_MANAGER:RegisterForEvent("MyAddonName_ChatMessageChannel", EVENT_CHAT_MESSAGE_CHANNEL, myChatMessageChannelCallbackFunction)

stAjora 04/28/15 05:03 PM

Thanks for the info. I got it working perfectly. Now I have a new issue where I have a few nested tables and at the end is a boolean, I ca'nt seem to check this value.
Code:

for key, value in pairs(table.table2.table3) do
    if(value == true) then
        d('true')
    elseif(value == false) then
        d('false')
    end
end

There is also the issue of concatenating values returned from a table. I'm assuming tostring() might be used but even so, it does nothing to get the following functioning as I expected.

Code:

local str = ""
for key, value in pairs(table) do
  str += value
end


Lastly, is there really no way to send information to the chat through an add on? Of course d() but no one will see messages you log with a d(). The only thing I can think of (and have yet to test) is adding text to the input line of the chat and letting the user press enter.

TribeofOne 04/28/15 05:30 PM

Quote:

Originally Posted by stAjora (Post 20953)

Lastly, is there really no way to send information to the chat through an add on? Of course d() but no one will see messages you log with a d(). The only thing I can think of (and have yet to test) is adding text to the input line of the chat and letting the user press enter.

http://www.esoui.com/downloads/info8...atAdverts.html
like this maybe?

Baertram 04/28/15 05:37 PM

Quote:

Originally Posted by stAjora (Post 20953)
There is also the issue of concatenating values returned from a table. I'm assuming tostring() might be used but even so, it does nothing to get the following functioning as I expected.

Code:

local str = ""
for key, value in pairs(table) do
  str += value
end


I don't know if the += possibility is given within lua.
You could do it this way:

Lua Code:
  1. local str = ""
  2. for key, value in pairs(table) do
  3.    str = str .. value
  4. end

circonian 04/28/15 06:23 PM

Quote:

Originally Posted by stAjora (Post 20953)
Thanks for the info. I got it working perfectly. Now I have a new issue where I have a few nested tables and at the end is a boolean, I ca'nt seem to check this value.
Code:

for key, value in pairs(table.table2.table3) do
    if(value == true) then
        d('true')
    elseif(value == false) then
        d('false')
    end
end


I may be missunderstanding, but from the way you phrased it, is the boolean the only value in table3 ?
Do you know the name of the boolean? like:
Lua Code:
  1. table = {
  2.   table2 = {
  3.    table3 = {
  4.       booleanIWantToCheck = true,
  5.    }
  6.   }
  7. }
  8. -- If so then you can check it with:
  9. if table.table2.table3.booleanIWantToCheck == true then
  10.    -- do whatever
  11. end

Using paris loops through every object in table 3, which is probably not what you want.
Like if you had:
Lua Code:
  1. table = {
  2.   table2 = {
  3.    table3 = {
  4.       otherBoolean = true
  5.       booleanIWantToCheck = false,
  6.       someString = "hello",
  7.    }
  8.   }
  9. }
using pairs(..) like you did would loop through all of those values: otherBoolean , booleanIWantToCheck , someString checking if each one is true or false.

stAjora 04/28/15 06:35 PM

Quote:

...
["Girdle"] = {
["Sturdy"] = {},
["Impenetrable"] = {},
["Reinforced"] = {},
["Well-fitted"] = {}, -- check capitalization
["Training"] = {},
["Infused"] = {},
["Exploration"] = {},
["Divines"] = {},
["Nirnhoned"] = {}
}
Figured out the problem. The last item in my array chain was an empty array thats why it never evaluated correctly. Needed to do value[1] to get the bool inside of each item. Then the string does concatenate correctly because it's not trying to stick in memory addresses.


As you can see, I'm collecting all information regarding a players researched traits. I tried to do this dynamically but I couldn't figure it out. Shouldn't be able to build the complete tree craft->weapon_type->trait with a couple loops?


All times are GMT -6. The time now is 01:53 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2014 - 2022 MMOUI