Wordfilter plugin README
(plugins@xsia.com)

Wordfilter is a palace server plugin which allows member and guest input
to be scanned for forbidden words.  The input scanned includes, normal
chat, whispers, room messages, global messages, screen names, and room
names.  If a forbidden word is found, the user's input is suppressed.
In addition, optional messages are sent to the server log, and to the
logged on wizards.


Installation

The following installation instructions assume that the Palace server
has been installed in /usr/local/palace.

Wordfilter is a standard Palace server plugin.  It is installed by
placing the plugin file, wordfilter.so, in the palace binary folder,
/usr/local/palace/bin, and adding the following line to the plugin
configuration file, /usr/local/palace/<palace-name>/psdata/plugin.conf:

../bin/wordfilter.so psdata/transtab psdata/words

The two control files, transtab, and words (described below) are placed
in /usr/local/palace/<palace-name>/psdata.  Note that wordfilter only
reads these files.  Therefore, they can be edited while the server is
running and reloaded with a command to wordfilter.


Method of Operation

The user input (gods and wizards are exempt) is converted to a cononical
form by:

  1. Translating it character by character with the translate table
     built from the transtab file.  Note that translation only affects
     the input to the word test.  It does not affect the user input that
     is passed to the server.

  2. Converting all strings of single character words to words.  For
     example, the input: "I want to k i l l" will be converted to,
     "I want to kill".

Then the input is checked against the words listed in the words file.


The transtab file

The transtab file consists of 256 hexadecimal characters which define
the input translation.  If the character # appears on a line, the rest
of the line is treated as a comment.  Two characters have special processing.

Any character which translates to 0xff is removed from the stream.  For
example, if the character | is defined to translate to 0xff, then the
input "k|i|l|l" will be translated to "kill".

Any character which translates to 0x00 is forbidden and wordfilte
immediately rejects the input.

It is highly recommended that any tables translate upper case letters to
lower case letters.  If this is not done, and it is desired to forbid
the word "kill" in all its permutations, there must be 16 entries in the
words file: kill, kilL, kiLl, kiLL, kIll, kIlL, kILl, kILL, Kill, KilL,
KiLl, KiLL, KIll, KIlL, KILl, and KILL.

Sample transtab:

# Special characters:
#  ff is removed from the string before testing
#  00 causes the string to be immediately rejected
#
# 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
 00 00 00 00 00 00 00 00 00 00 0a 00 00 0d 00 00 # 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # 10
#    !  "  #  $  %  &  '  (  )  *  +  ,  -  .  /
 20 ff ff ff ff 00 ff ff ff ff ff ff ff ff ff ff # 20
# 0  1  2  3  4  5  6  7  8  9  :  ;  <  =  >  ?
 30 31 32 33 34 35 36 37 38 39 ff ff ff ff ff ff # 30
# @  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O
 ff 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f # 40
# P  Q  R  S  T  U  V  W  X  Y  Z  [  \  ]  ^  _
 70 71 72 73 74 75 76 77 78 79 7a ff ff ff ff ff # 50
# `  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o
 ff 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f # 60
# p  q  r  s  t  u  v  w  x  y  z  {  |  }  ~  ^?
 70 71 72 73 74 75 76 77 78 79 7a ff ff ff ff 00 # 70
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # 80
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # 90
#   ݰ        *                    
 20 ff 63 6c ff 79 ff ff ff 63 61 ff ff ff 72 ff # a0
#                               
 ff ff ff ff ff 75 70 ff ff 31 6f ff ff ff ff ff # b0
#                                
 61 61 61 61 61 61 65 63 65 65 65 65 69 69 69 69 # c0
# -  -  "  "  '  '                    
 64 6e 6f 6f 6f 6f 6f 78 6f 75 75 75 75 79 70 62 # d0
#                               
 61 61 61 61 61 61 65 63 65 65 65 65 69 69 69 69 # e0
#                               
 6f 6e 6f 6f 6f 6f 6f ff 6f 75 75 75 75 79 70 79 # f0


The words file

The words file defines the words that will cause user input to be
rejected.  A word may be defined using * as a wildcard.  A leading *
causes all words ending with the specified word to be rejected.
Similarly, a trailing * causes all words which start with the specified
word to be rejected.  Both leading and trailing * cause all words
containing the specified word as a substring to be rejected.  For
example:

 Entry    Some words which are rejected

  kill             kill

  kill*            kill
                   killed
                   killer
                   killers
                   killing
                   killings
                   killjoy
                   kills

  *kill            kill
                   overkill
                   skill

  *kill*           kill
                   killed
                   killer
                   killers
                   killing
                   killings
                   killjoy
                   kills
                   overkill
                   skill
                   skilled
                   skillet
                   skillful
                   skillfully
                   skillfulness
                   skills
                   unskilled

It is recommended that entries using wildcards be tested against a
dictionary with a utility such as grep.  In many Unixes, the commands:

grep '^kill' /usr/dict/words   -- will test kill*,
grep 'kill$' /usr/dict/words   -- will test *kill, and
grep 'kill' /usr/dict/words   -- will test *kill*.

Note that when the data in the words file is read, it is translated with
transtab.  With a transtab which translates all upper case to lower
case, this allows upper case letters in the words list to compare equal
to user's input after translation.


Wizard and god commands

Wordfilter accepts several commands from users with wizard or god status.

`wordfilter log [on|off]    - Controls whether messages are sent to
                              server log when a forbidden word is
                              detected.
`wordfilter wizmsg [on|off] - Controls whether messages to wizards
                              and gods are sent when a forbidden word
                              is detected.
`wordfilter reload          - Causes the transtab and words files to
                              be read, replacing the old files.
`wordfilter test <line>     - Tests <line> against the current
                              transtab and words and reports the
                              result.


Fun with wordfilter

While wordfilter is primarily a tool to control forbidden language,
there are some games it makes possible that might be fun during certain
Palace events.  For example, an event can be declared, "No words with
"E" in them are permitted."  Or, "No words ending in "ing" or "in" are
permitted."
