Could not get spell name in WOW addon - world-of-warcraft

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

Related

Can't get the text from LineEdit to pass to a function

Context:
I click on a button -> a WindowDialogue appears -> there are 2 LineEdit Nodes and a button
Supposed procedure:
I fill these LineEdits, press the button, and the function tied to the button receives the texts from the LineEdits (and creates a dictionary key-value pair).
Problem:
The texts from the LineEdits do not pass down to the function (through connect()).
I tried passing the text directly with LineEdit.text. I tried writing it in a different variable and passing the variable. The debug shows the function is getting executed (no problem with that), but the strings passed from the LineEdits are always empty. Somehow, it worked for some time when I explicitly pressed ENTER after filling the LineEdits. But after I tried to fix the aforementioned problem, it stopped working altogether.
P.S. Everything I mentioned is created dynamically through the code, if that matters.
Code:
#Declaring the variables
var temp_text_key = ""
var temp_text_value = ""
#Function to show up a dialogue window with LineEdits and Confirm button
func _on_add_new_property(dict: Dictionary):
temporal_window_dialogue = WindowDialog.new()
temporal_window_dialogue.rect_min_size = Vector2(410,90)
temporal_window_dialogue.resizable = true
temporal_window_dialogue.popup_exclusive = true
temporal_window_dialogue.window_title = "Adding new property to %s" % get_dict_name_by_id(professions, dict["id"])
var le_key = LineEdit.new()
le_key.placeholder_text = "Name of the property"
le_key.hint_tooltip = "Name of the property"
le_key.connect("text_changed", self, "_on_add_new_prop_text_entered", ["key"])
var le_value = LineEdit.new()
le_value.expand_to_text_length = true
le_value.placeholder_text = "Value of the property"
le_value.set("custom_constants/minimum_spaces", 36)
le_value.hint_tooltip = "Value of the property"
le_value.connect("text_changed", self, "_on_add_new_prop_text_entered", ["value"])
var lab = Label.new()
lab.text = "Should the Value become a Dictionary?"
var check_bt = CheckBox.new()
var vbox = VBoxContainer.new()
var grid_container = GridContainer.new()
grid_container.columns = 2
var accept_bt = Button.new()
accept_bt.text = "Confirm"
temporal_window_dialogue.add_child(vbox)
vbox.add_child(grid_container)
grid_container.add_child(le_key)
grid_container.add_child(le_value)
grid_container.add_child(lab)
grid_container.add_child(check_bt)
vbox.add_child(accept_bt)
grid_container.set("custom_constants/vseparation", 5)
grid_container.set("custom_constants/hseparation", 5)
check_bt.connect("pressed", self, "_on_check_dict_pressed")
popup_window.add_child(temporal_window_dialogue)
temporal_window_dialogue.connect("popup_hide", self, "_on_close_specific_codegenerated_popup", [temporal_window_dialogue])
temporal_window_dialogue.popup_centered()
accept_bt.connect("pressed", self, "_on_add_new_property_confirmation", [dict, temp_text_key, temp_text_value])
#Function to create a new key/value pair in a dictionary
func _on_add_new_property_confirmation(dict: Dictionary, prop_name: String, prop_value: String):
if prop_name == "" or prop_value == "":
send_message_to_console("Neither of the two can be empty", 3)
return
if add_dictionary_flag:
dict[prop_name] = {
prop_value: {
"id": get_free_local_id_for_dict(dict)
}
}
elif !add_dictionary_flag:
if keywords_for_dictionaries.has(prop_name):
send_message_to_console("Only Dictionary items can become %s" % prop_name)
dict[prop_name] = prop_value
temp_text_key = ""
temp_text_value = ""
#Optional function to write the text from LineEdits to the variables
func _on_add_new_prop_text_entered(new_text, key_or_value):
if key_or_value == "key":
temp_text_key = new_text
elif key_or_value == "value":
temp_text_value = new_text
You mentioned using 'LineEdit.text', but have you tried the following?
var text = LineEdit.get_text()
If this doesn't help, please update your original post to include code examples.

How to get the client's ip on the server for remote desktop

I am using the following function to implement a program that changes its behavior depending on the IP of the connected PC.
There is a problem with this function that if something tries to login and fails, it may get the IP of the failed one.
And now that we've encountered that possibility, the program is broken.
What edits do I need to make to make this function behave as expected?
import psutil
def get_ip(port=3389):
ip = ""
for x in psutil.net_connections():
if x.status == "ESTABLISHED" and x.laddr.port == port:
ip = x.raddr.ip
break
I changed the function based on Bijay Regmi's comment. Thank you. wmi was difficult for me, so I used win32evtlog to read it out little by little. I am working on improving readability and finding bugs little by little.
def systime(xml):
return datetime.fromisoformat(xml.find(f'{ns}System/{ns}TimeCreated').get('SystemTime')[:-2] + "+00:00")
def last_event(handle,
event_id,
condition: Callable[['Event'], bool] = None) -> Optional['Event']:
now = datetime.now(tz=timezone.utc)
while True:
events = win32evtlog.EvtNext(handle, 20)
if not events:
break
for event in events:
xml_content = win32evtlog.EvtRender(event, win32evtlog.EvtRenderEventXml)
obj = Event(ET.fromstring(xml_content))
if obj.EventID == event_id:
if obj.SystemTime + timedelta(minutes=5) < now:
return None
if condition and not condition(obj):
continue
return obj
class Event:
def __init__(self, xml: ET.Element):
self.EventID = xml and xml.find(f'{ns}System/{ns}EventID').text
self.SystemTime = xml and systime(xml)
self.xml = xml
if self.EventID == '24':
self.IpAddress = xml.find(f'{ns}UserData/{{Event_NS}}EventXML/{{Event_NS}}Address').text
elif self.EventID == '4624':
self.IpAddress = xml.find(f'{ns}EventData/{ns}Data[#Name="IpAddress"]').text
else:
self.IpAddress = None

Smiles bot in Lua: matching text

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

Python3 socket doesn't work - graphite

I created a function to send data to a graphite server. It sends the metricname, value and the timestamp to the graphite server at execution:
def collect_metric(metricname, value, timestamp):
sock = socket.socket()
sock.connect( ("localhost", 2003) )
sock.send("%s %s %s\n" % (metricname, value, timestamp))
sock.close()
This function above worked fine in Python2. I had to rewrite this function for Python3. Now no data will be send to graphite. No log entries in the graphite/carbon logs or something else ...:
def collect_metric(metricname, value, timestamp):
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect( ("localhost", 2003) )
metricname = metricname.encode()
if type(value) == "str":
value = value.encode()
timestamp = timestamp.encode()
message = bytearray()
message = bytes(metricname+b" "+value+b" "+timestamp)
sock.sendall(message)
print(message.decode())
sock.close()
I receive no errors. Also on terminal I get the right format/output (see "print(message.decode())")
Has anybody some ideas why it doesn't work?
Thanks.
The bytearray is without any encoding. Try this:
message = (metricname+" "+value+" "+timestamp).encode("UTF-8")
sock.send(messages)
It seems like you're missing '\n' at the end of the message you're sending
message = bytes(metricname+b" "+value+b" "+timestamp)
should be:
message = bytes(metricname+b" "+value+b" "+timestamp + '\n')

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.

Resources