Graal Forums

Graal Forums (https://forums.graalonline.com/forums/index.php)
-   Code Gallery (https://forums.graalonline.com/forums/forumdisplay.php?f=179)
-   -   Clientside Swear Filter (https://forums.graalonline.com/forums/showthread.php?t=85382)

Tigairius 04-30-2009 11:56 PM

Clientside Swear Filter
 
As you may or may not know, I am one of the pioneers in removing foul language around Graal. I don't like to read it, I don't like to write it, I don't want to hear it, I don't want to see it.

However, I believe that people should have the choice as to whether or not they want to see the text or not.

So, I have devised a quick clientside swear filter for those of you who agree.

It probably needs to be improved in the future to run more efficiently, but this is a nice step in the right direction. You will still have to filter your PMs using the default graal rules.txt which is highly recommended, but now you can add a choice to whether or not the player wants to filter the swear words.

Here is the weapon script:
PHP Code:

//#CLIENTSIDE
function onCreated() {
  
this.swearwords = {
    {
"testing""*******"},
    {
"test2""*******"},
    {
"damn""****"}
  };
}

function 
onPlayerChats() {
  switch (
player.chat) {
    case 
"filteron":
      
client.swearfilter true;
      
player.chat "Swear filter is now on!";
    break;
    case 
"filteroff":
      
client.swearfilter false;
      
player.chat "Swear filter is now off.";
    break;
  }
}

function 
onRemotePlayerChats(objchat) {
  if (
client.swearfilter) {
    for (
temp.0temp.this.swearwords.size(); temp.++) {
      if (
obj.chat.pos(this.swearwords[temp.s][0]) >= 0) {
        
obj.chat replacetext(obj.chatthis.swearwords[temp.s][0], this.swearwords[temp.s][1]);
      } 
    }
  }
}

// edited version of my replacetext function in the code gallery
// http://forums.graalonline.com/forums/showthread.php?t=79538
// this one is not case sensitive
function replacetext(textoldtextnewtext) {
  
temp.oldlen   oldtext.length();
  
temp.textdiff newtext.length() - temp.oldlen;
  
  for (
temp.ptext.lower().positions(oldtext.lower())) {
    
temp.pos temp.temp.textdiff * (temp.index ++);
    
text text.substring(0temp.pos) @ newtext text.substring(temp.pos temp.oldlen);
  }
  
  return 
text;


As you can see, I added an example of how to turn on/off the sear filter by using the commands "filteron" and "filteroff."

I'd like to start seeing these sort of methods used around Graal to prevent foul language.

fowlplay4 05-01-2009 12:25 AM

Neat, I'm just confused by that continue.

On Zodiac, players can right click the target and ignore the players chat entirely.

Tigairius 05-01-2009 12:28 AM

Quote:

Originally Posted by fowlplay4 (Post 1487989)
Neat, I'm just confused by that continue.

I was going to add some more stuff under it but I decided not to and just never removed the continue, I've removed it now though.

Quote:

Originally Posted by fowlplay4 (Post 1487989)
On Zodiac, players can right click the target and ignore the players chat entirely.

That's a nice feature. I thought about adding something like that to GK but figured it might be a little excessive.

cbk1994 05-01-2009 12:29 AM

Nice, I like it better than a mandatory filter.

However, it would be better if it cached filtered text, e.g. something like...

PHP Code:

if (this.cache.(@ pl.chat) != null && pl.chat != null) {
  
pl.chat this.cache.(@ pl.chat);
} else {
  
// filter chat and save to cache


Only problem is it could potentially become a huge cache. Could help by using a single character to represent chat that doesn't need to be removed, rather than storing every single chat tidbit. I'm sure you'll think of something.

It just seems really inefficient to filter every single players chat twenty times a second.

Tigairius 05-01-2009 12:31 AM

Quote:

Originally Posted by cbk1994 (Post 1487991)
Nice, I like it better than a mandatory filter.

However, it would be better if it cached filtered text, e.g. something like...

PHP Code:

if (this.cache.(@ pl.chat) != null && pl.chat != null) {
  
pl.chat this.cache.(@ pl.chat);
} else {
  
// filter chat and save to cache


Only problem is it could potentially become a huge cache. Could help by using a single character to represent chat that doesn't need to be removed, rather than storing every single chat tidbit. I'm sure you'll think of something.

It just seems really inefficient to filter every single players chat twenty times a second.

Yes, I also thought of some nice innovative ways of remaking it, but this sample is supposed to be about as simple as possible so it will hopefully motivate people to build on top of it and make a nice filter system.

Also, usually when Graal is loading very long strings into vars it sometimes pauses the screen for up to 5-20 seconds depending on the size, which wouldn't be good.

Loriel 05-01-2009 12:35 AM

Ideally we would petition Stefan for a callback that gets fired if other players chat. I am not a huge fan of the timeout loop, especially since it keeps running even while the check is disabled.

cbk1994 05-01-2009 12:37 AM

Quote:

Originally Posted by Loriel (Post 1487994)
Ideally we would petition Stefan for a callback that gets fired if other players chat. I am not a huge fan of the timeout loop, especially since it keeps running even while the check is disabled.

Timeouts in themselves are not really inefficient, and the code Tig is using if not enabled simply schedules an event in another twentieth of a second.

Keep in mind that computers these days are extremely fast, and running a single check for something that is already loaded into memory will cause virtually no performance drops.

Tigairius 05-01-2009 12:43 AM

Quote:

Originally Posted by Loriel (Post 1487994)
Ideally we would petition Stefan for a callback that gets fired if other players chat. I am not a huge fan of the timeout loop

I agree completely.

Chompy 05-01-2009 12:05 PM

Quite neat I must say.

I did a little edit to remove that timeout :)

PHP Code:

//#CLIENTSIDE
function onCreated() {
  
this.swearwords = {
    {
"testing""*******"},
    {
"test2""*******"},
    {
"damn""****"}
  };
}

function 
onPlayerChats() {
  switch (
player.chat) {
    case 
"filteron":
      
client.swearfilter true;
      
player.chat "Swear filter is now on!";
    break;
    case 
"filteroff":
      
client.swearfilter false;
      
player.chat "Swear filter is now off.";
    break;
  }
}

function 
onRemotePlayerChats(objchat) {
  if (
client.swearfilter) {
    for (
temp.0temp.this.swearwords.size(); temp.++) {
      if (
obj.chat.pos(this.swearwords[temp.s][0]) >= 0) {
        
obj.chat replacetext(obj.chatthis.swearwords[temp.s][0], this.swearwords[temp.s][1]);
      } 
    }
  }
}

// DustyPorViva's replacetext function.
function replacetext(txt,a,b) {
  if (
txt.pos(a)<0) return txt;
  
temp.txtpos txt.positions(a);
  
temp.newtxt txt.substring(0,txtpos[0]);
  for (
temp.i=0;i<txtpos.size();i++) {
    
newtxt @= b;
    
newtxt @= txt.substring(txtpos[i]+a.length(),txt.substring(txtpos[i]+a.length()).pos(a));
  }
  return 
newtxt;



Gambet 05-01-2009 06:16 PM

Quote:

Originally Posted by Chompy (Post 1488119)
Quite neat I must say.

I did a little edit to remove that timeout :)

PHP Code:

//#CLIENTSIDE
function onPlayerChats() {
  switch (
player.chat) {
    case 
"filteron":
      
client.swearfilter true;
      
player.chat "Swear filter is now on!";
    break;
    case 
"filteroff":
      
client.swearfilter false;
      
player.chat "Swear filter is now off.";
    break;
  }




There is no need to use a switch() in this case and it's bad habit to do so. Not sure about how many other languages this applies to, but with Java you can't compare strings using switch(), so you wouldn't be able to apply the same method in Java. There are only select instances where it would actually make sense to use switch() instead of if-then-else, and this isn't one of them.

Also, it would benefit you to get into the habit of doing client.whatever = !client.whatever since it would save you an unnecessary clutter when doing something like this.

Tigairius 05-01-2009 07:12 PM

Quote:

Originally Posted by Chompy (Post 1488119)
Quite neat I must say.

I did a little edit to remove that timeout :)

Oh, nice, there IS an event for it. :D Thanks

Quote:

Originally Posted by Gambet (Post 1488194)
There is no need to use a switch() in this case and it's bad habit to do so. Not sure about how many other languages this applies to, but with Java you can't compare strings using switch(), so you wouldn't be able to apply the same method in Java. There are only select instances where it would actually make sense to use switch() instead of if-then-else, and this isn't one of them.

That's correct, Java's switch() statements only allow ints, but that doesn't mean I should model my code after the standards Java runs. You may notice that GScript2 utilizes strings much differently than most coding languages. Following that logic I should also declare all of my variables before using them even though they're automatically declared when they're not equal to NULL.

Quote:

Originally Posted by Gambet (Post 1488194)
Also, it would benefit you to get into the habit of doing client.whatever = !client.whatever since it would save you an unnecessary clutter when doing something like this.

It really isn't necessary for this... if someone said filteron and it was currently on it would just switch it off. An extra line or two really isn't a big deal in my opinion.

Rufus 05-01-2009 07:40 PM

Quote:

Originally Posted by Tigairius (Post 1487982)
I'd like to start seeing these sort of methods used around Graal to prevent foul language.

Why don't you try to get it added as a default feature, rather than some servers using it and others not?

Tigairius 05-01-2009 07:46 PM

Quote:

Originally Posted by Rufus (Post 1488211)
Why don't you try to get it added as a default feature, rather than some servers using it and others not?

I'd like to try to, there will also need to be one for PMs and one for nick names (nick names are easy to do).

Rufus 05-01-2009 08:06 PM

Quote:

Originally Posted by Tigairius (Post 1488213)
I'd like to try to, there will also need to be one for PMs and one for nick names (nick names are easy to do).

Well, I fully agree with the concept so I hope it is added. I think it'd be way more convenient if it was a part of the default Graal options, with the filter enabled by default of course. I believe that using asterisks represent the profanity too much though and it carries the negative/offensive connotation, just not as direct. A better way of conveying a more 'family friendly' message would be using random non-letter and non-punctuation (# & § @ %) symbols as a replacement like comic books do. With this you don't really notice that people are swearing, and unlike the current visual representation of obscenities, it no longer offends.

fowlplay4 05-01-2009 08:16 PM

Thanks to Chompy my filter script is now down to a couple lines!

PHP Code:

//#CLIENTSIDE
function onRemotePlayerChats(objchat) {
  if (
obj.account in client.chatignorelist)
    
obj.chat ".CI."



Gambet 05-01-2009 08:48 PM

Quote:

Originally Posted by Tigairius (Post 1488204)
That's correct, Java's switch() statements only allow ints, but that doesn't mean I should model my code after the standards Java runs. You may notice that GScript2 utilizes strings much differently than most coding languages. Following that logic I should also declare all of my variables before using them even though they're automatically declared when they're not equal to NULL.

Not true, Java's switch() does not only allow ints (it also allows char, byte, and short types), and for that matter, switch() works the same in just about every other popular language (such as C++ which was used largely in making Graal).

I'm not saying you shouldn't use strings in switch() statements on Graal, I'm just pointing out that other languages wouldn't allow you to do that. Regardless, though, I still feel that it was quite unnecessary in this case.


Quote:

Originally Posted by Tigairius (Post 1488204)
It really isn't necessary for this... if someone said filteron and it was currently on it would just switch it off. An extra line or two really isn't a big deal in my opinion.

I agree that it isn't so important for this example, but when you're dealing with large scripts (such as the code for Windows that is well past millions of lines), it is quite important to shorten the number of lines as much as possible. Just a general tip. :)

Loriel 05-01-2009 09:48 PM

Quote:

Originally Posted by Gambet (Post 1488233)
Not true, Java's switch() does not only allow ints (it also allows char, byte, and short types), and for that matter, switch() works the same in just about every other popular language (such as C++ which was used largely in making Graal).

All the languages that do switch statements and only allow you switch on integral types do that on account of having copied the syntax pretty much verbatim from C.

D lets you switch on strings, perl does not let you switch at all unless you write your own switchiness, ruby lets you switch on pretty much goddamn anything that defines an operator for matching a switch case. In Haskell and Nemerle, a switch-like structure is the basic low-level control structure and works for everything as well.

Quote:

Regardless, though, I still feel that it was quite unnecessary in this case.
I think it is purely a matter of style, here. Checking a variable against a sequence of values looks neater if you do not have to repeat the "variable ==" over and over, but all the break;s are pretty annoying too, I guess. :)

Quote:

I agree that it isn't so important for this example, but when you're dealing with large scripts (such as the code for Windows that is well past millions of lines), it is quite important to shorten the number of lines as much as possible. Just a general tip. :)
No, generally you want to make sure your code is as readable and maintainable as possible. The number of lines should only enter it a whole lot after that.

cbk1994 05-01-2009 09:56 PM

Quote:

Originally Posted by Loriel (Post 1488251)
No, generally you want to make sure your code is as readable and maintainable as possible. The number of lines should only enter it a whole lot after that.

I agree.

fowlplay4 07-14-2009 06:04 AM

I finally scripted this into Zodiac today, instead of censoring swears with just stars I wrote a function to do the whole @#$!% thing.

REPLACE (percentsign) with the actual character

PHP Code:

//#CLIENTSIDE
function getCensored(str) {
  
temp.symbols "!@#$(percentsign)&";
  
temp.int(random(0symbols.length()));
  for (
temp.0temp.str.length(); temp.i++) {
    
temp.newstr @= symbols.charat((temp.temp.i) (percent signsymbols.length());
  }
  return 
temp.newstr;


Usage..

PHP Code:

//#CLIENTSIDE
// Assuming we're using Dusty's Replace Text Function
temp.str "This sentence doesn't contain any stupid swears";
temp.swear "stupid";
temp.str replacetext(temp.strtemp.sweargetCensored(temp.swear)); 


devilsknite1 07-23-2010 06:37 PM

Sorry for reviving, but what's wrong with
PHP Code:

player.chat.contains() 

lol... Just seems a little bit easier to me, dunno :P

Loriel 07-23-2010 06:43 PM

If you just use a.contains(b) you only know whether a contains b but not where

devilsknite1 07-24-2010 07:01 AM

Err, I mean
PHP Code:

containsplayer.chatblah ); 

Oh and true, sorry, I wasn't thinking lol


All times are GMT +2. The time now is 09:30 AM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2025, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.