PDA

View Full Version : [Eluna] Simple World Chat System



slp13at420
01-02-2015, 12:26 AM
World Chat

<MOD><Release>

a simple World Chat system with adjustable colors and channel name.

this is a mutation of Foereaper's chat script.

I modified this so you wont need to type '#chat' every time you type a message.
to use this just change to `/say` channel then type '#chat on' to turn your access on then type away :D.
Once your done just type '#chat off' to turn your access off.
Name colors are team based. Ally blue, Horde red.

Contains a duration timer to help manage rapid spamming.
this should ignore add-on messages. - unteseted -
now supports the `.reload Eluna` command.




-- by slp13at420 of EmuDevs.com
-- a mutation of FoeReaper's world chat with basic bells an whistles.
-- simple world chat WITHOUT the '#chat' command...WTF you say?
-- just change to /say channel
-- turn it on
-- and chat away.
-- names are clickable for whispers and sub menu.

local WorldChat = {};
local channel_name = "World Chat";
local on = "#chat on";
local off = "#chat off";
local duration = 5; -- in seconds.

local Colors = { -- colors for names and misc
[0] = "|cff3399FF", -- blue for alliance name
[1] = "|cffFF0000", -- red for horde name
[3] = "|cff000000", -- black for [channel name]
[4] = "|cff00cc00", -- green for "message"
[5] = "|cff3399ff", -- good responce
[6] = "|cffFF0000", -- bad responce
};

local function ChatSystem(event, player, msg, type, lang, channel)

local acct_id = player:GetAccountId();

if not(WorldChat[acct_id])then

WorldChat[acct_id] = {
chat = 0,
time = GetGameTime()-duration,
};
end

if(lang ~= -1)then

if(msg ~= "")then

if(msg ~= "Away")then

if(msg == off)then
WorldChat[acct_id].chat = 0;
player:SendBroadcastMessage(Colors[5].."World chat off.|r")
return false;
end

if(msg == on)then
WorldChat[acct_id].chat = 1;
player:SendBroadcastMessage(Colors[5].."World chat on.|r")
return false;
end

if(WorldChat[acct_id].chat == 1)then -- 0 = world chat off :: 1 = world chat on

local time = GetGameTime();

if(time-WorldChat[acct_id].time >= duration)then

local t = table.concat{"[", Colors[3], channel_name, "|r]", "[", Colors[player:GetTeam()],"|Hplayer:", player:GetName(), "|h", player:GetName(), "|h", "|r]:", Colors[4], msg, "|r"};
SendWorldMessage(t);
WorldChat[acct_id].time = time;
else
player:SendBroadcastMessage(Colors[6].."World chat spam timer detected.|r")
end

return false;
end
end
end
end
end

RegisterPlayerEvent(18, ChatSystem)

print("Grumbo'z World Chat loaded.")



Alliance:
http://i.imgur.com/zRyVPBG.png
Horde:
http://i.imgur.com/ZsQrYrO.png

renatokeys
03-01-2016, 09:36 PM
545
look, carbonite addon spamm the world chat , how fix it ?

slp13at420
03-01-2016, 10:09 PM
hmm I need to add a check for duration of time passed...
maybe adjustable .. duration 5000ms or 5 seconds ? good ?

renatokeys
03-01-2016, 10:16 PM
but is a addon message, cant block the addon to send messages ?

slp13at420
03-01-2016, 10:36 PM
the messages look repetitive .. does the addon just keep chatting the same message??

renatokeys
03-01-2016, 10:46 PM
yes , they are using same addon , CARBONITE

Tommy
03-01-2016, 10:51 PM
but is a addon message, cant block the addon to send messages ?

You can still do what slp said even when it is an addon message. Though, I'm not sure how it will handle regardless.

You can see if the language type is of addon by doing:



if (lang == -1) then
-- Addon message
end


But you have to take into account some of the addons people use that don't specifically spam everyone but themselves. e.g. raid addons, etc.

I think a lot of people try to prevent actions like these and tend to overthink the code process. Not sure if you can prevent players from spamming addon messages or not, but there are ways to catch players doing this so you can kick or ban them. Could try implementing a mute system. Disabling addons? Not completely sure if you can do that, maybe, who knows. I guess this is the downside of a world chat nowadays?

slp13at420
03-01-2016, 11:09 PM
for this tho I think I can do something like (if lang == -1) AND (current message == prior message)

- - - Updated - - -

and then let it only spam the player.
so then any addon will chat at the player but not the world ... maybe lol

Try this renatokeys.






-- by slp13at420 of EmuDevs.com
-- a mutation of FoeReaper's world chat with basic bells an whistles.
-- simple world chat WITHOUT the '#chat' command...WTF you say?
-- just change to /say channel
-- turn it on
-- and chat away.
-- names are clickable for whispers and sub menu.

local ACCT = {};
local channel_name = "World Chat";
local on = "#chat on";
local off = "#chat off";
local duration = 5; -- in seconds.

local Team = { -- colors for names and misc
[0] = "|cff3399FF", -- blue for alliance name
[1] = "|cffFF0000", -- red for horde name
[3] = "|cff000000", -- black for [channel name]
[4] = "|cff00cc00", -- green for "message"
};

local function ChatLogon(event, player)

ACCT[player:GetAccountId()] = {
chat = 0,
time = GetGameTime(),
};
end

RegisterPlayerEvent(3, ChatLogon)

local function ChatSystem(event, player, msg, type, lang, channel)

if(lang ~= -1)then

if(msg ~= "")then

if(msg ~= "Away")then

local acctid = player:GetAccountId();
local time = GetGameTime();

if(msg == off)then
ACCT[acctid].chat = 0;
player:SendBroadcastMessage("|cff3399ffWorld chat off.|r")
return false;
end

if(msg == on)then
ACCT[acctid].chat = 1;
player:SendBroadcastMessage("|cff3399ffWorld chat on.|r")
return false;
end

if(ACCT[acctid].chat == 1)then -- 0 = world chat off :: 1 = world chat on
if(time-ACCT[acctid].time >= duration)then

local t = table.concat{"[", Team[3], channel_name, "|r]", "[", Team[player:GetTeam()],"|Hplayer:", player:GetName(), "|h", player:GetName(), "|h", "|r]:", Team[4], msg, "|r"};
SendWorldMessage(t);
ACCT[acctid].time = time;
else
player:SendBroadcastMessage("|cff3399ffWorld chat spam timer detected.|r")
end

return false;
end
end
end
end
end

RegisterPlayerEvent(18, ChatSystem)

print("Grumbo'z World Chat loaded.")


it doesn't do anything if the lang is -1 so it wont interfere with the player receiving the msg and it also has an adjustable time check for delay between messages.

hold on its frell'd

- - - Updated - - -

ok tested what I can but I don't have add-ons , it does work with delay check:





-- by slp13at420 of EmuDevs.com
-- a mutation of FoeReaper's world chat with basic bells an whistles.
-- simple world chat WITHOUT the '#chat' command...WTF you say?
-- just change to /say channel
-- turn it on
-- and chat away.
-- names are clickable for whispers and sub menu.

local ACCT = {};
local channel_name = "World Chat";
local on = "#chat on";
local off = "#chat off";
local duration = 5; -- in seconds.

local Team = { -- colors for names and misc
[0] = "|cff3399FF", -- blue for alliance name
[1] = "|cffFF0000", -- red for horde name
[3] = "|cff000000", -- black for [channel name]
[4] = "|cff00cc00", -- green for "message"
};

local function ChatLogon(event, player)

ACCT[player:GetAccountId()] = {
chat = 0,
time = GetGameTime(),
};
end

RegisterPlayerEvent(3, ChatLogon)

local function ChatSystem(event, player, msg, type, lang, channel)

if(lang ~= -1)then

if(msg ~= "")then

if(msg ~= "Away")then

local acctid = player:GetAccountId();
local time = GetGameTime();

if(msg == off)then
ACCT[acctid].chat = 0;
player:SendBroadcastMessage("|cff3399ffWorld chat off.|r")
return false;
end

if(msg == on)then
ACCT[acctid].chat = 1;
player:SendBroadcastMessage("|cff3399ffWorld chat on.|r")
return false;
end

if(ACCT[acctid].chat == 1)then -- 0 = world chat off :: 1 = world chat on
if(time-ACCT[acctid].time >= duration)then

local t = table.concat{"[", Team[3], channel_name, "|r]", "[", Team[player:GetTeam()],"|Hplayer:", player:GetName(), "|h", player:GetName(), "|h", "|r]:", Team[4], msg, "|r"};
SendWorldMessage(t);
ACCT[acctid].time = time;
else
player:SendBroadcastMessage("|cff3399ffWorld chat spam timer detected.|r")
end

return false;
end
end
end
end
end

RegisterPlayerEvent(18, ChatSystem)

print("Grumbo'z World Chat loaded.")


ok when language is -1 it should just pass thru to player. anything else will go to world chat where it then checks for duration between last world chat message.

Tommy
03-02-2016, 12:11 AM
Imo you should remove the prints. That's a lot of console spam and you said it already works, so there's no real point in keeping them. :P

slp13at420
03-02-2016, 12:17 AM
Imo you should remove the prints. That's a lot of console spam and you said it already works, so there's no real point in keeping them. :P

rofl good catch n fixed :D

`print` , best tool ever!!

Foereaper
03-02-2016, 12:18 AM
Why do you have so many empty else cases?

slp13at420
03-02-2016, 12:19 AM
Why do you have so many empty else cases?

ermm I was prepping for responces n ermm forgot to remove them too lol
ugh n fixed

Clastor
03-17-2016, 07:44 PM
lua_scripts/Chat23.lua:55: attempt to index field '?' (a nil value)

"if(ACCT[acctid].chat == 1)then -- 0 = world chat off :: 1 = world chat on"

any solution?

Rochet2
03-17-2016, 08:42 PM
did you use .reload eluna
?

I dont think the script is designed to be reloadable.

Clastor
03-17-2016, 09:29 PM
did you use .reload eluna
?

I dont think the script is designed to be reloadable.


Yes, reboot the server to run?

Rochet2
03-17-2016, 09:41 PM
Yes, reboot the server to run?

yes

Grandelf
03-17-2016, 10:48 PM
I was looking over the script and noticed that players are added to the table,
whenever they login. This concept seems nice enough, because you don't have to worry
about the data (table) in the actual script.

However, a player is always stored whether he uses the world chat or not.
This means that if a player doesn't use the world chat, the data stored is
pretty much useless. No nitpicking here, just sharing some thoughts which might
improve the script =P.

So you could actually achieve the exact same result, without storing data
that isn't used. We can do this by using an __index metamethod.
You could replace:

local ACCT = {};
With:


local ACCT = setmetatable({}, {
__index = function (t, k)
t[k] = {
chat = 0,
time = os.time()
}
return t[k];
end
});

What this does is basically checking if a certain index exists. If it doesn't,
the function will create the table with the given index and return it.
If I'd run this code now: 'print(ACCT[1].chat)' it would actually print '0' instead
of giving an error that the index doesn't exist.

So rather than storing the data whenever a player enters world, the data is stored
whenever it is requested (ACCT[index that doesn't exist yet]).
With this in place, you could remove the login hook and the script would still work.
As a bonus, reloading the Lua Engine doesn't break the script anymore.

Again no nitpicking, just sharing some thoughts ;).

Grandelf

slp13at420
03-17-2016, 11:21 PM
I gottcha lol just wrap it up in the On Chat hoop check and make if needed like I do in guild warz for the location id's.
i'll update this :computerstare:

Grandelf
03-17-2016, 11:35 PM
You could do that as well, if you use the metatable however, you don't have to.

slp13at420
03-17-2016, 11:55 PM
ok re-organized it to support the `.reload Eluna` command and updated the main post :D




-- by slp13at420 of EmuDevs.com
-- a mutation of FoeReaper's world chat with basic bells an whistles.
-- simple world chat WITHOUT the '#chat' command...WTF you say?
-- just change to /say channel
-- turn it on
-- and chat away.
-- names are clickable for whispers and sub menu.

local WorldChat = {};
local channel_name = "World Chat";
local on = "#chat on";
local off = "#chat off";
local duration = 5; -- in seconds.

local Colors = { -- colors for names and misc
[0] = "|cff3399FF", -- blue for alliance name
[1] = "|cffFF0000", -- red for horde name
[3] = "|cff000000", -- black for [channel name]
[4] = "|cff00cc00", -- green for "message"
[5] = "|cff3399ff", -- good responce
[6] = "|cffFF0000", -- bad responce
};

local function ChatSystem(event, player, msg, type, lang, channel)

local acct_id = player:GetAccountId();

if not(WorldChat[acct_id])then

WorldChat[acct_id] = {
chat = 0,
time = GetGameTime()-duration,
};
end

if(lang ~= -1)then

if(msg ~= "")then

if(msg ~= "Away")then

if(msg == off)then
WorldChat[acct_id].chat = 0;
player:SendBroadcastMessage(Colors[5].."World chat off.|r")
return false;
end

if(msg == on)then
WorldChat[acct_id].chat = 1;
player:SendBroadcastMessage(Colors[5].."World chat on.|r")
return false;
end

if(WorldChat[acct_id].chat == 1)then -- 0 = world chat off :: 1 = world chat on

local time = GetGameTime();

if(time-WorldChat[acct_id].time >= duration)then

local t = table.concat{"[", Colors[3], channel_name, "|r]", "[", Colors[player:GetTeam()],"|Hplayer:", player:GetName(), "|h", player:GetName(), "|h", "|r]:", Colors[4], msg, "|r"};
SendWorldMessage(t);
WorldChat[acct_id].time = time;
else
player:SendBroadcastMessage(Colors[6].."World chat spam timer detected.|r")
end

return false;
end
end
end
end
end

RegisterPlayerEvent(18, ChatSystem)

print("Grumbo'z World Chat loaded.")



I did some random `.reload Eluna` command's and it seem to run smooooooth
altho ofc if you use `.reload Eluna` those who are using world chat will revert back to local chat until they turn it back on.

:D enjoy :D

TBH I never worked with metatables before.

Foereaper
03-19-2016, 01:09 AM
In the original script I later rewrote the cache to be created when the player actually sent a chat message rather than on login, due to the exact same "bug" (Oversight) you were having :P

revowow
08-12-2016, 05:16 AM
I found the way to do the [VIP] and such, the problem I would like to see instead of having to type #chat on, #chat off, is their a way to add /world ?

slp13at420
08-13-2016, 02:34 PM
I found the way to do the [VIP] and such, the problem I would like to see instead of having to type #chat on, #chat off, is their a way to add /world ?

you're talking about custom channels?
or using a channel for chat instead?

I did experiment with different ways of doing world chat.
There is another one for dedicating a channel to world chat --> https://github.com/BlackWolfsDen/World_Chat/blob/master/Eluna/World_Chat_Channel/World_Chat_Channel.lua
https://github.com/BlackWolfsDen/World_Chat/tree/master/CPP/Dedicated-Channel-World-Chat
you jump on the pre-chosen channel `/1` and just chat away.

as far as making a new channel like `/world` I have no knowledge yet on how-to but i'm sure someone here can point you in the right direction.

revowow
08-13-2016, 10:03 PM
Ok i go thte /1 to work with the world, and my modifications, but the problem when you do /1 it shows /1 General-Yourlocation. is their a way to change this in c++?
Like would you know where channel names are defined? are they code wize or dbc file

slp13at420
08-14-2016, 02:05 AM
hmmm I don't know how to edit the names nor add a new channel but I think you may find something here ... it would be the first place I would start looking are these files here:
\src\server\game\Chat