Smiles bot in Lua: matching text - string

This is my bot, who copies smilies in game chat.
The smiles it copies are saved in the table called "emoticons". If someone writes ":)", the bot writes ":)" and so on
The code inside the loop is for this: if someone writes, for example, ">:)", you have to make the script copy ">:)" and not just ":)"
CreateFrame, RegisterEvent, SetScript and SendChatMessage are in-game built Lua API
local emoticons = {
":)", "(:", ":))", ">:)", "0:)", ":D", ":]", ":)))", "=]", "?_?", "+.+", ":P", ":3", "^^", "roar", ":V", "D:", ":C", ".D", ".)", "o_o",
"^-^", ":PPP", ":DDD", ":D:D:D", ":DDDD", ":D:D:D:D", ":DDDDD", ":d", ":L", "<O>_<O>", "o/", "+_+", "?_?", "*0*", ":}", ";)", ":))))", "o.o", "<.<''", ":|",
":-)", "^^^^", ":D:D:D:D:D:D", ":D :D :D", "^^^", ":c", ";]", ":9", ">:|", ">.<", ";3", ";P", "T_T", ":3c", ":)))))",
"^^^^^" }
local f = CreateFrame("Frame")
f:RegisterEvent("CHAT_MSG_GUILD")
f:SetScript("OnEvent", function(self, event, text, playerName, _, channelName, playerName2, _, _, channelIndex)
local msg
local n = 0
for x, key in ipairs(emoticons) do
local l = string.len(emoticons[x])
if (string.sub(text, -l) == emoticons[x]) then
if (l > n) then
msg = emoticons[x]
n = l
end
end
end
if (msg) and (playerName ~= UnitName("player")) then
if (event == "CHAT_MSG_GUILD") then SendChatMessage(msg, "GUILD", nil, channelIndex) end
end
end)
Is there any way to improve it? For example, if someone writes
"^^^^^^"
the bot copies
"^^^^^"
which would be the same with one less "^" as it was stored in the table
My goal is that if someone writes, for example, "^^^^^^" and it is not registered in the table, the script will not respond

You're probably better off learning how to use string.gmatch
As an example, let's say you only store one instance of ':D' in your emoticons table. You can iterate through the matches and respond in kind. Here's a small example:
local text = ':D:D:D'
local count = 0
for w in string.gmatch(text, ':D') do
count = count + 1
end
if count > 0 then
local response = ''
for i = 1, count do
response = response .. ':D'
end
print(response) -- prints ':D:D:D'
end
This doesn't handle every case, but hopefully it can help you get started
:D

Related

Could not get spell name in WOW addon

Trying to get name of a spell as it seems like
local spellName = select(1, CombatLogGetCurrentEventInfo())
returns something like numbers instead plain text like 158989565.009
I was trying to get spell name by function GetSpellInfo(i) but no luck
Here is code sample that doesn't work:
local frame = CreateFrame("FRAME");
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
frame:SetScript("OnEvent", function(self, event)
local type = select(1, CombatLogGetCurrentEventInfo())
if (type == "SPELL_DAMAGE") then
local spellId = select(1, CombatLogGetCurrentEventInfo())
local name = GetSpellInfo(spellId)
SendChatMessage(name, "SAY", "COMMON", GetUnitName("PLAYERTARGET"));
end
end)
Late answer but see https://wow.gamepedia.com/COMBAT_LOG_EVENT
local playerGUID = UnitGUID("player")
local MSG_SPELL_DAMAGE = "Damaged %s with %s"
local frame = CreateFrame("Frame");
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
frame:SetScript("OnEvent", function(self, event)
local timestamp, subevent, _, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags, spellId, spellName, spellSchool = CombatLogGetCurrentEventInfo()
if subevent == "SPELL_DAMAGE" and sourceGUID == playerGUID then
print(MSG_SPELL_DAMAGE:format(destName, spellName))
end
end)
Example message

Corona sdk : stop audio when another starts / launch audio just once

I want to stop a sound when another starts playing .
if (event.object1.myName == "obst3") then
audio.play(colsound)
I want this one to stop if the following one starts .
if (event.object1.myName == "t") then
audio.play(explosion)
Also, I need to know how to launch the sound just once ( when my objects collide with a wall, a sound pop out I need this one to be heard just once even if the player touches again the wall.
Play every audio with reference id value :
if (event.object1.myName == "obst3") then
local isChannel1Playing = audio.isChannelPlaying( 2 )
if isChannel1Playing then
audio.stop( playLaserSound2 )
playLaserSound2 = nil
end
playLaserSound1 = audio.play(colsound, { channel=1 })
end
if (event.object1.myName == "t") then
local isChannel1Playing = audio.isChannelPlaying( 1 )
if isChannel1Playing then
audio.stop( playLaserSound1 )
playLaserSound1 = nil
end
playLaserSound2 = audio.play(explosion, { channel=2 })
end

How do you use lua in redis to return usable result to nodejs

one of the module i am implementing for my mobile app api is to get all outstanding notifications from , submitting username.
i used a list called username:notifications to store all outstanding id of notifications.
For example, in my test case, ['9','10',11'] is the result after calling for
lrange username:notifications 0 -1
So i wrote a lua script to get lrange and for each result,
hgetall notification:id
And for some reason, lua could not send the table, result to nodejs in usable state. Wondering if anyone
has a solution for multiple hgetall requests and returning them to nodejs
Here goes the rest of the code:
-- #KEYS: "username"
-- #ARGV: username
-- gets all fields from a hash as a dictionary
local hgetall = function (key)
local bulk = redis.call('HGETALL', key)
local result = {}
local nextkey
for i, v in ipairs(bulk) do
if i % 2 == 1 then
nextkey = v
else
result[nextkey] = v
end
end
end
local result = {}
local fields = redis.call('LRANGE' , ARGV[1], 0,-1)
for i, field in ipairs(fields) do
result[field] = hgetall('notification:'..field)
end
return result
You cannot return a "dictionary" from a Lua script, it is not a valid Redis type (see here).
What you can do is something like this:
local result = {}
local fields = redis.call('LRANGE' , ARGV[1], 0, -1)
for i=1,#fields do
local t = hgetall('notification:' .. fields[i])
result[#result+1] = fields[i]
result[#result+1] = #t/2
for j=1,#t do
result[#result+1] = t[j]
end
end
return result
The result is a simple list with this format:
[ field_1, nb_pairs_1, pairs..., field_2, nb_pairs_2, ... ]
You will need to decode it in your Node program.
EDIT: there is another solution, probably simpler in your case: encode the result in JSON and return it as a string.
Just replace the last line of your code by:
return cjson.encode(result)
and decode from JSON in your Node code.

Lua - Cipher Logic Error Involving string.gsub, Ciphered Output is Not Input

My program seems to be experiencing logical errors. I have looked it over multiple times and even written another program similar to this one (also seems to have the same error). I cannot figure out what is wrong, although I think it may involve my usage of string.gsub...
repeat
local file = io.open("out.txt", "w")
print("would you like to translate Cipher to English or English to Cipher?")
print("enter 1 for translation to English. enter 2 for translation to Cipher")
tchoice=io.read()
if tchoice=="2" then
print(" enter any text to translate it: ")
rawtextin=io.read()
text=string.lower(rawtextin)
text1=string.gsub(text,"a","q")
text2=string.gsub(text1,"b","e")
text3=string.gsub(text2,"c","h")
text4=string.gsub(text3,"d","c")
text5=string.gsub(text4,"e","j")
text6=string.gsub(text5,"f","m")
text7=string.gsub(text6,"g","r")
text8=string.gsub(text7,"h","g")
text9=string.gsub(text8,"i","b")
text10=string.gsub(text9,"j","a")
text11=string.gsub(text10,"k","d")
text12=string.gsub(text11,"l","y")
text13=string.gsub(text12,"m","v")
text14=string.gsub(text13,"n","z")
text15=string.gsub(text14,"o","x")
text16=string.gsub(text15,"p","k")
text17=string.gsub(text16,"q","i")
text18=string.gsub(text17,"r","l")
text19=string.gsub(text18,"s","f")
text20=string.gsub(text19,"t","s")
text21=string.gsub(text20,"u","w")
text22=string.gsub(text21,"v","t")
text23=string.gsub(text22,"w","p")
text24=string.gsub(text23,"x","u")
text25=string.gsub(text24,"y","n")
text26=string.gsub(text25,"z","o")
text27=string.gsub(text26," ","#")
print(text27)
elseif tchoice=="1" then
print("enter text!")
rawtextin=io.read()
text=string.lower(rawtextin)
text1=string.gsub(text,"q","a")
text2=string.gsub(text1,"e","b")
text3=string.gsub(text2,"h","c")
text4=string.gsub(text3,"c","d")
text5=string.gsub(text4,"j","e")
text6=string.gsub(text5,"m","f")
text7=string.gsub(text6,"r","g")
text8=string.gsub(text7,"g","h")
text9=string.gsub(text8,"b","i")
text10=string.gsub(text9,"a","j")
text11=string.gsub(text10,"d","k")
text12=string.gsub(text11,"y","l")
text13=string.gsub(text12,"v","m")
text14=string.gsub(text13,"z","n")
text15=string.gsub(text14,"x","o")
text16=string.gsub(text15,"k","p")
text17=string.gsub(text16,"i","q")
text18=string.gsub(text17,"l","r")
text19=string.gsub(text18,"f","s")
text20=string.gsub(text19,"s","t")
text21=string.gsub(text20,"w","u")
text22=string.gsub(text21,"t","v")
text23=string.gsub(text22,"p","w")
text24=string.gsub(text23,"u","x")
text25=string.gsub(text24,"n","y")
text26=string.gsub(text25,"o","z")
text27=string.gsub(text26,"#"," ")
print(text27)
end
print("writing to out.txt...")
file:write(text27)
file:close()
print("done!")
print("again? type y for yes or anything else for no.")
again=io.read()
until again~="y"
x=io.read()
No errors in the code - What am I missing? I am aware this is not the most efficient way of doing this but I need to figure out what is going wrong before I write a more efficient program using loops and tables.
Sample run (with only significant data included):
in:2
in:hi test
out:gb#safs
in:y
in:1
in:gb#safs
out:hq vjvv
local decoded = 'abcdefghijklmnopqrstuvwxyz #'
local encoded = 'qehcjmrgbadyvzxkilfswtpuno# '
local enc, dec = {}, {}
for i = 1, #decoded do
local e, d = encoded:sub(i,i), decoded:sub(i,i)
enc[d] = e
dec[e] = d
end
repeat
local file = io.open("out.txt", "w")
local text27, rawtextin
print("would you like to translate Cipher to English or English to Cipher?")
print("enter 1 for translation to English. enter 2 for translation to Cipher")
local tchoice = io.read()
if tchoice == "2" then
print(" enter any text to translate it: ")
rawtextin = io.read()
text27 = rawtextin:lower():gsub('.',enc)
print(text27)
elseif tchoice == "1" then
print("enter text!")
rawtextin = io.read()
text27 = rawtextin:lower():gsub('.',dec)
print(text27)
end
print("writing to out.txt...")
file:write(text27)
file:close()
print("done!")
print("again? type y for yes or anything else for no.")
local again = io.read()
until again ~= "y"

Writing data to excel files, MATLAB

I am using MatlabR2011a on my Windows 7 machine.
I have a folder of 635 text files. Each file contains multiple rows and 2 columns. I am trying to loop through the folder and read each file and write these values to excel. So far this is what I have:
close all; clc;
dirname = uigetdir;
Files = dir(fullfile(dirname,'*.txt'))
for k = 1:635
j =1
filename = fullfile(dirname,Files(k).name);
fid = fopen(filename);
x = fgetl(fid)
while ischar(x)
x = fgetl(fid)
a2 = strtrim(x);
a3 = textscan(a2,'%s');
a4 = a3{1}{1};
a5= a3{1}{2};
pos3 = strcat('A',num2str(j));
xlswrite('sample_output',{a4,a5},'Sheet1',pos3)
j = j+1;
end
fclose(fid);
end
It keeps giving me the following error after finishing reading the first file.
Error using ==> strtrim Input should be a string or a cell array of strings.
A sample input file looks like this:
15076 4636259
15707 4636299
15714 1781552
15721 4204950
15730 2174919
16209 4636510
16413 4758572
16470 4445808
17519 311397
17667 2116489
17739 1729694
18024 3210756
18627 3714194
18695 4192858
19141 632766
19318 1923574
19438 1255216
19493 4635020
19771 4770250
How can I fix this? Would appreciate help with this!
In the while loop, cut the line
x=fgetl(fid)
...and paste it before the end statement right after j=j+1.
The error occurs because you get a line before the while statement, then you use the while statement to test validity of the string (all fine so far), but then immediately get the subsequent line before you perform your string operation. The call to fgetl at the start of the while block could return an EOF, causing subsequent string manipulation functions to fail.
Also... The code would be more robust if you set your for loop like so
for k=1:numel(Files)
Since all your data are numeric this should work. Give it a try.
dirname = uigetdir;
Files = dir(fullfile(dirname,'*.txt'))
j =0;
for k = 1:numel(Files)
filename = fullfile(dirname,Files(k).name);
x = dlmread(filename,'\t'); %# I assume tab-delimiter
j = j + size(x, 1);
xlswrite( 'sample_output', x, 'Sheet1',sprintf('A%d',j) )
end

Resources