• This is a read only backup of the old Emudevs forum. If you want to have anything removed, please message me on Discord: KittyKaev

[Eluna] Simple World Chat System

slp13at420

Mad Scientist
World Chat

<MOD><Release>

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

this is a mutation of [MENTION=7]Foereaper[/MENTION]'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.

Code:
[COLOR="#808080"]
-- 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.")
[/COLOR]

Alliance:
zRyVPBG.png

Horde:
ZsQrYrO.png
 
Last edited:

slp13at420

Mad Scientist
hmm I need to add a check for duration of time passed...
maybe adjustable .. duration 5000ms or 5 seconds ? good ?
 

Tommy

Founder
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:

Code:
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

Mad Scientist
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 [MENTION=810]renatokeys[/MENTION].

Code:
[COLOR="#808080"]


-- 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.")[/COLOR]

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:

Code:
[COLOR="#808080"]

-- 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.")
[/COLOR]

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.
 
Last edited:

Tommy

Founder
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
 

Clastor

Enthusiast
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?
 

Grandelf

Esteemed Member
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:
Code:
local ACCT = {};
With:
Code:
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

Mad Scientist
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:
 

slp13at420

Mad Scientist
ok re-organized it to support the `.reload Eluna` command and updated the main post :D

Code:
[COLOR="#808080"]
-- 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.")
[/COLOR]

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.
 
Last edited:
Top