ID:2313666
 
(See the best response by Spunky_Girl.)
I want to mute someone so they can't talk in the chat. I searched the forums and found two different codes:

mob
var/muted = 0


var/list/muted = list()


The first one uses a variable under mob that a moderator can set to true or false. For the second one, the moderator has to add the person to a global list.

Which one should I use? If I use the first one and the person just relogs, will they still be muted? Similar for the second one, if I reboot the world will then the list become empty?
Best response
The first method can work as long as the variable gets saved (isn't a tmp var). The second method works as long as you save the list into a savefile, much like saving a player.
Yeah, I mean you can save whatever you want. lol

In general if you save a mob you are saving all of its vars (unless you save variables individually, which... you probably should), so like Spunky said it will save the muted variable with the player. If you use a list you will have to save that list manually in world/Del() and load it in world/New(). Neither is inherently right or wrong -- programming contains many different roads that all lead to the same location. It seems like you understand how the variables themselves work so I don't feel I need to go into further detail, but if you have any other questions feel free to ask. :)
mob
var
list/MuteList=list()
list/MuteListKey=list()
mutetime = 0
muted = 0
mutereason=0

verb
Mute()
var/list/onlinePlayers = list()
for(var/mob/player/M in world)
if(M.client) onlinePlayers += M
var/mob/M = input("Who would you like to Mute?","Mute Player") as null|anything in onlinePlayers
if(!M) return
if(M.muted)
usr << "<font color=gray>[M] is already muted for [M.mutetime] minutes"
return
else
var/reason = input("Why do you want to mute [M] ([M.key])?","Mute [M] ([M.key])")as text|null
if(!reason)
reason = "no reason"
var/time = input("How many minutes would you like to mute [M] ([M.key]) for?\
\n- You cannot mute over 500 minutes\n- You cannot mute lower than 1\
\n- Enter 0 to exit
[M]'s punishment","Time (In Minutes)")as num|null
if(!time) return
if(time >= 500)
time = 500
if(time <= 0) return
time = round(time)
M.muted = 1
M.mutereason = "[reason]; Muted by [usr.key]; Original Time: [time] Minutes"
M.mutetime = time
M.Mute_Timer()
if(!MuteList) MuteList=list()
MuteList+=M.client.address
MuteListKey+=M.key
UnMute()
var/list/onlinePlayers = list()
for(var/mob/player/M in world)
if(M.client && M.muted) onlinePlayers += M
var/mob/M = input("Who would you like to Unmute?","Unmute Player")as null|anything in onlinePlayers
if(!M) return
if(M.muted || M.mutetime)
MuteList-=M.client.address
MuteListKey-= M.key
M.muted = 0
M.mutetime = 0
M.mutereason = null
world<<"[alert] [M] ([M.key]) has been un-muted by [usr]"
else
usr<<"<font color=red>They don't appear to be muted"
return
mob
proc
Mute_Timer()
spawn(600)
if(src.muted)
src.mutetime --
if(src.mutetime <= 0)
src.mutetime = 0
src.muted = 0
src.mutereason = null
MuteList-=src.client.address
world<<"world alert: [src] ([src.key]) has been unmuted"
if(src.muted) src.Mute_Timer()
Auto_Mute()
if(src.muted) return
if((src.key in MuteListKey) || (src.client.address in MuteList))
var/time = 60
var/reason = "Mute Avoid"
world<<"world info [src] ([src.key]) has been auto-muted for [time] minutes for [reason]"
src.muted = 1
src.mutetime = time
src.mutereason = "[reason]; Muted by Auto-Mute-Check; Original Time: [time] Minutes"
src.Mute_Timer()

Here is the example of how it should be done. Someone correct me please if im wrong I did this in hurry so I didn`t have time to test it out. Please do not coppy past this. It is the example!
Yeah, it's indeed the same as I tested it too. Ok, I have another small question about the mute verb though. I obviously need to use a mob as an argument. So, do I use:

mute(mob/m)


or

mute(mob/m in world)


Does the "in world" thing play any role?
In response to Quadrillion
Quadrillion wrote:
Yeah, it's indeed the same as I tested it too. Ok, I have another small question about the mute verb though. I obviously need to use a mob as an argument. So, do I use:

> mute(mob/m)
>

or

> mute(mob/m in world)
>

Does the "in world" thing play any role?

I am 99% certain the first snippet defaults to in world anyway.

If you have a list that keeps track of actual players though, you could (and probably should) use that, as it's much smaller of a list.




var/list/MuteList = list()

proc
mute(mob/m)
for(m in world)
MuteList+= m


@Phat T: I have an idea of what you wanted to do, but your code is far from it.
In response to FKI
You are correct. It does default to the world list if none is specified. But why are we assuming mobs have to be used in this scenario? Looping through clients would bypass the need for making a "connected players" list entirely. In fact, making a chat system solely for clients is probably the better path to go anyways since AI mobs have no purpose having player chat functionalities. It'd be wasted resources.

And for my nitpicking portion...

As per the green programming article (here), it's not best to initialize empty lists during compile time. It's, again, a waste of resources to have a list that's empty, but not garbage collected. Initializing them only when you want to add things to them, and then deleting them when you remove the last item from them, is the appropriate way to go.

@Phat T
Stop.

@Synpax
Although we know you're trying to help, the way you are implementing this type of system isn't quite up to snuff. It's a good baseline for improvement, though. I'd change a few aspects of it, such as that Mute_Timer() proc entirely and using clients from the get-go are just for starters.
Phat T wrote:
> var/list/MuteList = list()
>
> proc
> mute(mob/m)
> for(m in world)
> MuteList+= m

This is how I would do it.
This ignores any given m and just adds all mobs in the world to MuteList.

I definitely wouldn't add the mob itself to any lists. If anything, you would add the mob's key to the list. You wouldn't want the mob to be saved separately; that causes rollbacks and the mob to exist before the client.
In response to Spunky_Girl
Looping through clients would bypass the need for making a "connected players" list entirely.

How? You would still be looping through in world to grab clients.
Making a connected players list is pointless. You're better off just looping through existed clients. Use a list instead of individual variables so that you can unmute or append a string to the list without them being online. Save the list on world del. I would go into more detail but mobile.
As for the mute timer assign their mute time to world.realtime + the time they're muted form next time they type and if they are added to the mute list, compare that variable to world.realtime. if world.realtime is greater, remove them from the mute list.
Yeah. Did some performance tests to compare and even mob in world performs better than a "players online" list, as does searching for a client in the world. Perhaps this would scale differently with more mob/client instances to grab (I was only using one of each), I don't know.
That's weird
In response to FKI
Seems you answered your own question. Good show.