Is there a way to get the last chat massage in shout or say? - lua

I want to search the last message for a few strings and then echo the message back with those strings replaced with other strings.
I searched multiple documentations but didn't find a way to get the last message.
This is the first forum I ask as I already have an account so have no real starting point to give you.
Thanks in advance!

There is no way in the WoW API to get the last chat message of a specific channel. You will have to handle the CHAT_MSG_CHANNEL event (see Event Handling) to read all messages, and store the newest one. Specifically for the say or yell (shout) channels there are the CHAT_MSG_SAY and CHAT_MSG_YELL events respectively.
To do this your addon needs to own a Frame, these frames can register event handlers and you will have to store the last message you receive from that handler in a local variable in your script (let's call it last_message). Then when your other piece of code executes you can read the last_message variable:
local frame = CreateFrame("FRAME", "FooAddonFrame");
local last_message = nil;
frame:RegisterEvent("CHAT_MSG_CHANNEL");
local function eventHandler(self, event, ...)
-- Look up the arguments that are given to your specific event
-- and assign them to variables in order by retrieving them from
-- the `...` variable arguments
local msg, author, language, channel = ...
print("Hello World! Hello " .. event);
last_message = msg
end
frame:SetScript("OnEvent", eventHandler);

Related

Discordia bot DM sending breaks my script

I am trying to make a bot for my server on discord using Discordia, but when I try to use member:send(str), all I get is Uncaught Error: C:/luvit/deps/coro-channel.lua:62: C:/luvit/deps/discordia/libs/containers/User.lua:91: attempt to call method 'getPrivateChannel' (a nil value)
it does send the dm, but then the code breaks and the bot doesn't run anymore, how can I fix this?
member is a variable that gets the member from message
local member = message.member
I am able to recreate the issue, albeit with a different error that I suspect is due to me not having all your code to debug with.
The bot will send the DM and post a message, then crash due to error.
You have this code:
if message.content:lower() == prefix..'createdm' then
message.channel:send("<#!"..memberid.."> ".. "Sent!")
message.member:send("test") --message.member is able to inherit the send method from message.author
end
I don't know how you find memberid, so I defined it like this:
memberid = message.member:__hash()
It is called every time a message is sent, and it sends a message. This means the bot is going to call this and read its own messages. While the bot will not continue into the if statement because its message is not <prefix>createdm, it will still try to get memberid and evaluate the if statement. I do not know how bot users differ from human users in their account metadata, but I strongly suspect there is some difference and this is your issue.
I believe adding this to your code, at the beginning of your message callback (before your do anything else to evaluate a message) will fix your problem.
if message.author == client.user then
return
end
client here is whatever you assigned discordia.Client() to.
if message.content:lower() == prefix..'createdm' then
message.channel:send("<#!"..memberid.."> ".. "Sent!") -- member.id !!!
message.member:send("test") --message.member is able to inherit the send method from message.author
end

Bailing people out of prison in roblox using Remote Events doesn't seem to work properly

Here's the deal. When you get arrested in my game, you get sent to jail. To get out you must be bailed out.
The client sends a request to the server to bail them. Every other part seems to work except this part I believe, however it could be the client side script. Is there anything incorrect about this script? I have checked it for any errors that are obvious to me.
local replicatedStorage = game:GetService('ReplicatedStorage')
local createSystemMessage = replicatedStorage:WaitForChild('CreateSystemMessage')
game.ReplicatedStorage.Bail.OnServerEvent:Connect(function(Player,PlayerToBail)
Player = game.Players:FindFirstChild(Player)
local tab = nil
for i,v in pairs(_G.GlobalData) do
if v.Name == Player.Name then
tab = v
end
end
if PlayerToBail.Team == game.Teams:FindFirstChild("Criminal") then
local Bounty = PlayerToBail.leaderstats.Bounty.Value * 2
if tab.Bank <= Bounty then
tab.Bank -= Bounty
PlayerToBail.leaderstats.Bounty.Value = 0
PlayerToBail.Prisoner.Value = false
PlayerToBail.Team = game.Teams:FindFirstChild("Civilian")
createSystemMessage:FireAllClients((Player.Name .. ' has Bailed ' .. PlayerToBail.Name), Color3.fromRGB(0, 250, 0))
end
end
end)
And the local script which works:
script.Parent.AcceptButton.MouseButton1Click:Connect(function()
local PlayerName = script.Parent.TargetName.Text
game.ReplicatedStorage.Bail:FireServer(PlayerName)
print ("Bail Requested")
end)
I believe the problem occurs with the argument you're passing to the remote event.
In your client script you pass PlayerName as an argument. I'm assuming this is a string of the player's name:
game.ReplicatedStorage.Bail:FireServer(PlayerName)
PlayerName will actually be sent to the parameter "PlayerToBail", which I'm assuming is supposed to be a player object. Keep in mind that Roblox's RemoteEvents automatically pass in the player who fired the remote event as the first argument. So the "Player" parameter of the function connected to your remote event is the actual player object that has the local script that fired the remote event.
Instead, I would fire the remote event like this:
game.ReplicatedStorage.Bail:FireServer()
Since the player you want to bail is automatically passed as an argument, you don't need to add any additional arguments to FireServer. In addition, you would get rid of the "PlayerToBail" parameter in your server script.
Also note, it is unnecessary to have this line of code in your server script:
Player = game.Players:FindFirstChild(Player)
Player is already referring to an object in game.Players. In addition, Player is an object, not a string. So this would not work. You can simply use Player as is for your purposes.
More info on Remote Events: https://developer.roblox.com/en-us/articles/Remote-Functions-and-Events
Please feel free to follow up if you still have issues.
When firing the server it automatically gives a parameter which is the player who sent it. So, you don't have to have the playerName part because after the player parameter is already there and you can get the name from that.

How do i use socket.select?

I need some help using socket "select" function.
My server code is like this:
while true do
for _,server in pairs(servers) do
local client = server:accept()
client:settimeout(5)
local line, err = client:receive()
if not err then
client:send(line .. "_SERVER_SIDE\n")
else
client:Send("___ERRORPC"..err)
end
client:close()
end
end
But now i want to use the select function instead of make a forever loop like this.
Reading this: http://w3.impa.br/~diego/software/luasocket/socket.html
I know that i can use something simmilar than:
socket.select(servers, nil, 5)
But i donĀ“t know how i can use this on the code above. Can anyone help me?
I will have to use this inside a while true statement?
The reading operation (first parameter) means that i can only make an accept/receive]? And the seconds parameter means that i can only make a send?
As per the documentation, select receives one or two arrays of sockets and returns an array of sockets that can safely be read from without blocking and an array of sockets that can be safely written to without blocking and an array of sockets that can safely be written without blocking. An important point is that the first array is for both server sockets that want you want to call accept on and for client sockets that you want to call receive on.
The seconds parameter is just a timeout for the select. It doesn't have to do with how many operations you can make.
The basic thing you are going to have to change in your code is that when a receive call fails with a timeout, instead or giving an error you should add that socket to the array of sockets that you pass to select. This way you can have select tell you when that socket becomes active again.
From the documentation for select: "calling select with a server socket in the receive parameter before a call to accept does not guarantee accept will return immediately. Use the settimeout method or accept might block forever." This means that you'd need to use settimeout before your accept call, but assuming you have a list of opened connections you can work with in servers table, you can use select in the following way:
local canread = socket.select(servers, nil, 1)
for _,client in ipairs(canread) do
local line, err = client:receive()
if not err then
client:send(line .. "_SERVER_SIDE\n")
else
client:send("___ERRORPC"..err)
end
end
socket.select will block for up to 1 second, but will return sooner if there is a socket from the list you provided that can be read from. You can block indefinitely if you use socket.select(servers, nil, 0); blocking for some short time is useful if you need to do some other work while waiting for the input.
Updated to use ipairs instead of pairs as the returns table is keyed both on numbers as well as on sockets themselves, so if one socket can be read from, the returned array looks like {[1] = sock, [sock] = 1}.
single demo
local server = socket.bind("*",7777)
local client_tab = {}
while true do
-- socket.select first param is a table of connected socket,
-- you want a connected socket,you need to call accept()
-- if you do not want to block,you should call settimeout(seconds)
local recvt = socket.select(client_tab, nil, 1)
server:settimeout(1)
local client = server:accept()
if client then
client_tab[#client_tab+1] = client
end
if #recvt > 0 then
-- read clients in recvt
end
end

World-of-Warcraft Chat Frame Filter Conflict

I have a WoW/LUA script that I am attempting to start, but it seems to conflict with the Stubby addon, which is a part of the Auctioneer addon, I believe. Here is the message I receive:
Error occured in: Stubby Count: 1 Message: Error: Original call failed
after running hooks for: ChatFrame_OnEvent Usage:
SendChatMessage(text [,type] [,language] [,targetPlayer]) Debug:
(tail call): ? [string ":OnEvent"]:1:
[string ":OnEvent"]:1
Now, the only thing that's happening in the conflicting addon is:
ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY", partyMsg)
The code within partyMsg is very simple as well:
local function partyMsg(msg,author,language,lineID,senderGUID)
if (store ~= msg) then
SendChatMessage(msg,"SAY",nil,nil);
end
store = msg;
end
Is this error due to two addons both trying to filter the chat frame? If so, how can this be done? It seems odd to me that Blizzard would have such a simple and yet important concept limited to one addon.
I think I see what happened here.
The reference you were using, Events/Communication, shows only the specific parameters for a particular event, regardless of context.
The context is usually an OnEvent handler.
The ChatFrame_AddMessageEventFilter function lets you use the chat frame's OnEvent handler instead of your own for chat frame events, and has well defined parameters for filters you add.
An OnEvent handler might look like:
function Foo_OnEvent(self, event, ...)
A 'ChatFrame' filter must look like this, for the first two parameters:
function Foo_ChatFrameFilter(self, event, msg, ...)
The ChatFrame filter is specific. For OnEvent however, you can make a Lua 'handler' that doesnt care about what frame it came from:
<OnEvent>
MyEventHandler(event, ...)
</OnEvent>
For the sake of completion, I will include the entire source of this addon:
local function partyMsg(someTable,msgType,msg,user,language,...)
if (store ~= msg) then
SendChatMessage(user .. " just said: ".. msg .. " using that sneaky " .. language .. " language.");
end
store = msg;
return false;
end
ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY", partyMsg)
ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY_LEADER",partyMsg)
There were a couple issues with the original code:
1) I was using WoWWiki to get my information, and first, I read it incorrectly. lineID and senderGUID are not the 4th and 5th arguments. Then, beyond this, WoWWiki is incorrect on this page in general. The correct arguments are listed above in the source. The first argument, a table, I am unsure of its purpose. In any case, this code now works fully.

What info is availble inside the pinfo parameter in a lua tshark listener?

So I'm looking at how listener taps work. What I've come up with at this point is:
my_tap = Listener.new(nil, "myfilter")
myvar = Field.new("something to look at")
-- then the callback
function my_tap.packet(pinfo)
-- format the time like os.date("%c", pinfo.abs_ts)
-- what else is in pinfo.???
-- lots of stuff
end
I have been unable to find any thorough documentation on what gets exposed to lua via the pinfo parameter to the packet callback. So far I have found *pinfo.abs_ts*. Which is great because tcp.options.timestamp.tsval seems to either be null or contain incorrect / incomplete information all the time.
What exactly gets exposed through pinfo? Is there a list of information I can pull somewhere other than pinfo.abs_ts?
wireshark.org/docs/wsug_html_chunked/lua_module_Pinfo.html seems to describe pretty much everything I was looking for

Resources