package com.planet_ink.coffee_mud.Libraries;
import com.planet_ink.coffee_mud.core.interfaces.*;
import com.planet_ink.coffee_mud.core.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.*;
import com.planet_ink.coffee_mud.Abilities.interfaces.*;
import com.planet_ink.coffee_mud.Areas.interfaces.*;
import com.planet_ink.coffee_mud.Behaviors.interfaces.*;
import com.planet_ink.coffee_mud.CharClasses.interfaces.*;
import com.planet_ink.coffee_mud.Commands.interfaces.*;
import com.planet_ink.coffee_mud.Common.interfaces.*;
import com.planet_ink.coffee_mud.Exits.interfaces.*;
import com.planet_ink.coffee_mud.Items.interfaces.*;
import com.planet_ink.coffee_mud.Locales.interfaces.*;
import com.planet_ink.coffee_mud.MOBS.interfaces.*;
import com.planet_ink.coffee_mud.Races.interfaces.*;
import java.util.*;
/*
Copyright 2000-2006 Bo Zimmerman
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
public class CoffeeFilter extends StdLibrary implements TelnetFilter
{
public String ID(){return "CoffeeFilter";}
public Hashtable tagTable=null;
public Hashtable getTagTable()
{
if(tagTable==null) tagTable=CMStrings.makeNumericHash(TelnetFilter.FILTER_DESCS);
return tagTable;
}
public String simpleOutFilter(String msg)
{
if(msg==null) return null;
StringBuffer buf=new StringBuffer(msg);
for(int i=0;i<buf.length();i++)
{
switch(buf.charAt(i))
{
case '`':
buf.setCharAt(i,'\'');
break;
case '\\':
if(i<buf.length()-1)
{
switch(buf.charAt(i+1))
{
case 'n':
case 'r':
{
buf.setCharAt(i,(char)13);
if((i>=buf.length()-2)||((i<buf.length()-2)&&((buf.charAt(i+2))!=10)))
buf.setCharAt(i+1,(char)10);
else
if(i<buf.length()-2)
buf.deleteCharAt(i+1);
}
break;
case '\'':
case '`':
{
buf.setCharAt(i,'\'');
buf.deleteCharAt(i+1);
}
break;
}
}
break;
}
}
return buf.toString();
}
// no word-wrapping, text filtering or ('\','n') -> '\n' translations
// (it's not a member of the interface either so probably shouldn't be public)
public String colorOnlyFilter(String msg, Session S)
{
if(msg==null) return null;
if(msg.length()==0) return msg;
StringBuffer buf=new StringBuffer(msg);
Session CS=S;
//if(CS==null) CS=(Session)CMClass.getCommon("DefaultSession");
int loop=0;
while(buf.length()>loop)
{
switch(buf.charAt(loop))
{
case '>':
if((S!=null)&&(S.clientTelnetMode(Session.TELNET_MXP)))
{
buf.delete(loop,loop+1);
buf.insert(loop,">".toCharArray());
loop+=3;
}
break;
case '"':
if((S!=null)&&(S.clientTelnetMode(Session.TELNET_MXP)))
{
buf.delete(loop,loop+1);
buf.insert(loop,""".toCharArray());
loop+=5;
}
break;
case '&':
if((S!=null)&&(S.clientTelnetMode(Session.TELNET_MXP)))
{
if((!buf.substring(loop,loop+3).equalsIgnoreCase("lt;"))
&&(buf.substring(loop,loop+3).equalsIgnoreCase("gt;")))
{
buf.delete(loop,loop+1);
buf.insert(loop,"&".toCharArray());
loop+=4;
}
}
else
if(loop<buf.length()-3)
{
if(buf.substring(loop,loop+3).equalsIgnoreCase("lt;"))
buf.replace(loop,loop+3,"<");
else
if(buf.substring(loop,loop+3).equalsIgnoreCase("gt;"))
buf.replace(loop,loop+3,">");
}
break;
case '<':
if((S!=null)&&(S.clientTelnetMode(Session.TELNET_MXP)))
{
buf.delete(loop,loop+1);
buf.insert(loop,"<".toCharArray());
loop+=3;
}
break;
case '^':
{
if((loop<buf.length()-1)&&(CS!=null))
{
int colorID = CS.getColor( buf.charAt(loop+1) );
if (colorID != -1)
{
String colorEscStr = CS.makeEscape(colorID);
int csl=0;
if (colorEscStr != null)
{
csl = colorEscStr.length();
if (csl > 0)
buf.replace(loop,loop+2 ,colorEscStr);
}
if (csl == 0)
{
// remove the color code
buf.deleteCharAt(loop);
buf.deleteCharAt(loop);
loop-=1;
}
else
if((colorID<('0'))||(colorID>('9')))
{
// begin MXP tags
if(buf.charAt(loop)=='<')
{
int tagStart=loop;
while(loop<(buf.length()-1))
{
if((buf.charAt(loop)!='^')||(buf.charAt(loop+1)!='>'))
{
loop++;
if(loop>=(buf.length()-1))
{
loop=tagStart;
break;
}
}
else
if(!S.clientTelnetMode(Session.TELNET_MXP))
{
buf.delete(tagStart,loop+2);
loop=tagStart-1;
break;
}
else
{
loop--;
break;
}
}
}
else
{
loop+=csl-1; // already processed 1 char
}
}
else
{
loop--;
}
}
}
break;
}
default:
break;
}
loop++;
}
if ((S!=null)&&(S.currentColor() != ('N'))&&(S.clientTelnetMode(Session.TELNET_ANSI)))
buf.append(S.makeEscape('N'));
return buf.toString();
}
public String getLastWord(StringBuffer buf, int lastSp, int lastSpace)
{
String lastWord="";
if(lastSp>lastSpace)
{
lastWord=CMStrings.removeColors(buf.substring(lastSpace,lastSp)).trim().toUpperCase();
while((lastWord.length()>0)&&(!Character.isLetterOrDigit(lastWord.charAt(0))))
lastWord=lastWord.substring(1);
while((lastWord.length()>0)&&(!Character.isLetterOrDigit(lastWord.charAt(lastWord.length()-1))))
lastWord=lastWord.substring(0,lastWord.length()-1);
for(int i=lastWord.length()-1;i>=0;i--)
if(!Character.isLetterOrDigit(lastWord.charAt(i)))
{ lastWord=lastWord.substring(i+1); break;}
}
else
{
for(int i=(lastSpace-1);((i>=0)&&(!Character.isLetterOrDigit(buf.charAt(i))));i--)
lastWord=buf.charAt(i)+lastWord;
lastWord=CMStrings.removeColors(lastWord).trim().toUpperCase();
}
return lastWord;
}
public String fullOutFilter(Session S,
MOB mob,
Environmental source,
Environmental target,
Environmental tool,
String msg,
boolean wrapOnly)
{
if(mob==null) return msg;
if(msg==null) return null;
if(msg.length()==0) return msg;
String newMsg=(S==null)?null:CMLib.lang().sessionTranslation(msg);
if((newMsg!=null)&&(msg!=null)) msg=newMsg;
boolean doSagain=false;
boolean firstSdone=false;
StringBuffer buf=new StringBuffer(msg);
int wrap=(S!=null)?S.getWrap():78;
int len=(wrap>0)?wrap:Integer.MAX_VALUE;
int loop=0;
int lastSpace=0;
int firstAlpha=-1;
while(buf.length()>loop)
{
int lastSp=-1;
while((loop<len)&&(buf.length()>loop))
{
switch(buf.charAt(loop))
{
case ' ':
{
if(lastSp>lastSpace)
lastSpace=lastSp;
lastSp=loop;
}
break;
case (char)13:
{
if(((loop<buf.length()-1)&&((buf.charAt(loop+1))!=10))
&&((loop>0)&&((buf.charAt(loop-1))!=10)))
buf.insert(loop+1,(char)10);
if(wrap>0) len=loop+wrap;
lastSpace=loop;
}
break;
case (char)10:
{
if(wrap>0) len=loop+wrap;
lastSpace=loop;
}
break;
case '`':
buf.setCharAt(loop,'\'');
break;
case '!':
if((loop<buf.length()-10)
&&(S!=null)
&&(buf.charAt(loop+1)=='!')
&&((buf.substring(loop+2,loop+7).equalsIgnoreCase("sound"))
||(buf.substring(loop+2,loop+7).equalsIgnoreCase("music"))))
{
int x=buf.indexOf("(",loop+7);
int y=buf.indexOf(")",loop+7);
if((x>=0)&&(y>=x))
{
if((S.clientTelnetMode(Session.TELNET_MSP))
&&((source==null)
||(source==mob)
||(CMLib.flags().canBeHeardBy(source,mob))))
{
loop=y;
if(wrap>0)
len=len+(y-loop)+1;
}
else
{
buf.delete(loop,y+1);
loop--;
}
}
}
break;
case '>':
if((S!=null)&&(S.clientTelnetMode(Session.TELNET_MXP)))
{
buf.delete(loop,loop+1);
buf.insert(loop,">".toCharArray());
loop+=3;
}
break;
case '"':
if((S!=null)&&(S.clientTelnetMode(Session.TELNET_MXP)))
{
buf.delete(loop,loop+1);
buf.insert(loop,""".toCharArray());
loop+=5;
}
break;
case '&':
if((S!=null)&&(S.clientTelnetMode(Session.TELNET_MXP)))
{
if((!buf.substring(loop,loop+3).equalsIgnoreCase("lt;"))
&&(!buf.substring(loop,loop+3).equalsIgnoreCase("gt;")))
{
buf.delete(loop,loop+1);
buf.insert(loop,"&".toCharArray());
loop+=4;
}
else
loop+=3;
}
else
if(loop<buf.length()-3)
{
if(buf.substring(loop,loop+3).equalsIgnoreCase("lt;"))
buf.replace(loop,loop+3,"<");
else
if(buf.substring(loop,loop+3).equalsIgnoreCase("gt;"))
buf.replace(loop,loop+3,">");
}
break;
case '%':
if(loop<buf.length()-2)
{
int dig1=hexStr.indexOf(buf.charAt(loop+1));
int dig2=hexStr.indexOf(buf.charAt(loop+2));
if((dig1>=0)&&(dig2>=0))
{
buf.setCharAt(loop,(char)((dig1*16)+dig2));
buf.deleteCharAt(loop+1);
if((buf.charAt(loop))==13)
buf.setCharAt(loop+1,(char)10);
else
buf.deleteCharAt(loop+1);
}
}
break;
case '(':
if((!wrapOnly)&&(loop<(buf.length()-1)))
{
char c2=Character.toUpperCase(buf.charAt(loop+1));
if(((loop<buf.length()-2)&&(buf.charAt(loop+2)==')')&&(c2=='S'))
||((loop<buf.length()-3)&&(buf.charAt(loop+3)==')')&&(Character.toUpperCase(buf.charAt(loop+2))=='S')&&((c2=='Y')||(c2=='E'))))
{
String lastWord=getLastWord(buf,lastSp,lastSpace);
int lastParen=(c2=='S')?loop+2:loop+3;
if(lastWord.equals("A")
||lastWord.equals("YOU")
||lastWord.equals("1")
||doSagain)
{
if(c2=='Y')
buf.replace(loop,lastParen+1,CMStrings.sameCase("y",buf.charAt(loop+1)));
else
buf.delete(loop,lastParen+1);
doSagain=true;
loop--;
}
else
{
if(c2=='Y')
buf.replace(loop,lastParen+1,CMStrings.sameCase("ies",buf.charAt(loop+1)));
else
{
buf.deleteCharAt(lastParen);
buf.deleteCharAt(loop);
}
}
firstSdone=true;
}
}
break;
case '\\':
if(loop<buf.length()-1)
{
switch(buf.charAt(loop+1))
{
case 'n':
case 'r':
{
buf.setCharAt(loop,(char)13);
if((loop>=buf.length()-2)||((loop<buf.length()-2)&&((buf.charAt(loop+2))!=10)))
buf.setCharAt(loop+1,(char)10);
else
if(loop<buf.length()-2)
buf.deleteCharAt(loop+1);
}
break;
case '\'':
case '`':
{
buf.setCharAt(loop,'\'');
buf.deleteCharAt(loop+1);
}
break;
}
}
break;
case '<':
if((!wrapOnly)&&((loop+1)<buf.length()))
{
// supported here <?-HIS-HER>, <?-HIM-HER>, <?-NAME>,
// <?-NAMESELF>, <?-HE-SHE>, <?-IS-ARE>, <?-HAS-HAVE>
//int endDex=loop;
StringBuffer cmd=new StringBuffer("");
int ldex=loop+1;
char lc=' ';
for(;(ldex<buf.length())&&(cmd!=null);ldex++)
{
lc=buf.charAt(ldex);
if(lc=='>')
break;
switch(lc)
{
case '<':
case '\n':
case '\r':
cmd=null;
break;
default:
cmd.append(Character.toUpperCase(lc));
break;
}
}
if((cmd!=null)&&(ldex<buf.length())&&(buf.charAt(ldex)=='>')&&(cmd.length()>1)&&(cmd.length()<14))
{
Environmental regarding=null;
switch(cmd.charAt(0))
{
case 'S': regarding=source; break;
case 'T': regarding=target; break;
case 'O': regarding=tool; break;
}
String replacement=null;
Integer I=(Integer)getTagTable().get(cmd.substring(1));
if(I==null)
{
if((S!=null)&&(S.clientTelnetMode(Session.TELNET_MXP)))
{
buf.delete(loop,loop+1);
buf.insert(loop,"<".toCharArray());
}
}
else
switch(I.intValue())
{
case NAME:
{
if(regarding==null)
replacement="";
else
if(mob==regarding)
{
replacement="you";
if(!firstSdone) doSagain=true;
}
else
if(((!CMLib.flags().canSee(mob))||(!CMLib.flags().canBeSeenBy(regarding,mob)))&&(regarding.Name().trim().length()>0))
replacement=((regarding instanceof MOB)?"someone":"something");
else
if(regarding instanceof MOB)
replacement=((MOB)regarding).displayName(mob);
else
replacement=regarding.name();
}
break;
case NAMENOART:
{
if(regarding==null)
replacement="";
else
if(mob==regarding)
{
replacement="you";
if(!firstSdone) doSagain=true;
}
else
if(((!CMLib.flags().canSee(mob))||(!CMLib.flags().canBeSeenBy(regarding,mob)))&&(regarding.Name().trim().length()>0))
replacement=((regarding instanceof MOB)?"someone":"something");
else
if(regarding instanceof MOB)
replacement=CMLib.english().cleanArticles(((MOB)regarding).displayName(mob));
else
replacement=CMLib.english().cleanArticles(regarding.name());
}
break;
case NAMESELF:
{
if(regarding==null)
replacement="";
else
if(((source==target)||(target==null))&&(mob==regarding))
replacement="yourself";
else
if(mob==regarding)
{
replacement="you";
if(!firstSdone) doSagain=true;
}
else
if(((!CMLib.flags().canSee(mob))||(!CMLib.flags().canBeSeenBy(regarding,mob)))&&(regarding.Name().trim().length()>0))
replacement=((regarding instanceof MOB)?"someone":"something");
else
if(source==target)
replacement=((regarding instanceof MOB)?(((MOB)regarding).charStats().himher()+"self"):"itself");
else
if(regarding instanceof MOB)
replacement=((MOB)regarding).displayName(mob);
else
replacement=regarding.name();
}
break;
case YOUPOSS:
{
if(regarding==null)
replacement="";
else
if(mob==regarding)
replacement="your";
else
if(((!CMLib.flags().canSee(mob))||(!CMLib.flags().canBeSeenBy(regarding,mob)))&&(regarding.Name().trim().length()>0))
replacement=((regarding instanceof MOB)?"someone's":"something's");
else
if(regarding instanceof MOB)
replacement=((MOB)regarding).displayName(mob)+"'s";
else
replacement=regarding.name()+"'s";
}
break;
case HISHER:
{
if(regarding==null)
replacement="";
else
if(mob==regarding)
replacement="your";
else
if(regarding instanceof MOB)
replacement=((MOB)regarding).charStats().hisher();
else
replacement="its";
}
break;
case HIMHER:
{
if(regarding==null)
replacement="";
else
if(mob==regarding)
{
replacement="you";
if(!firstSdone) doSagain=true;
}
else
if(regarding instanceof MOB)
replacement=((MOB)regarding).charStats().himher();
else
replacement="it";
}
break;
case HIMHERSELF:
{
if(regarding==null)
replacement="themself";
else
if(mob==regarding)
replacement="yourself";
else
if(regarding instanceof MOB)
replacement=((MOB)regarding).charStats().himher()+"self";
else
replacement="itself";
}
break;
case HISHERSELF:
{
if(regarding==null)
replacement="themself";
else
if(mob==regarding)
replacement="yourself";
else
if(regarding instanceof MOB)
replacement=((MOB)regarding).charStats().hisher()+"self";
else
replacement="itself";
}
break;
case HESHE:
{
if(regarding==null)
replacement="";
else
if(mob==regarding)
{
replacement="you";
if(!firstSdone) doSagain=true;
}
else
if(regarding instanceof MOB)
replacement=((MOB)regarding).charStats().heshe();
else
replacement="its";
}
break;
case SIRMADAM:
{
if(regarding==null)
replacement="";
else
if(regarding instanceof MOB)
replacement=((MOB)regarding).charStats().sirmadam();
else
replacement="sir";
}
break;
case ISARE:
{
if(regarding==null)
replacement="";
else
if(mob==regarding)
replacement="are";
else
if(regarding instanceof MOB)
replacement="is";
}
break;
case ISARE2:
{
String lastWord=getLastWord(buf,lastSp,lastSpace);
if((lastWord.equals("A")||lastWord.equals("YOU")||lastWord.equals("1")||doSagain))
replacement="is";
else
replacement="are";
}
break;
case HASHAVE:
{
if(regarding==null)
replacement="";
else
if(mob==regarding)
replacement="have";
else
if(regarding instanceof MOB)
replacement="has";
}
break;
}
if(replacement!=null)
{
String newReplacement=CMLib.lang().filterTranslation(replacement);
if(newReplacement!=null) replacement=newReplacement;
buf.delete(loop,ldex+1);
buf.insert(loop,replacement.toCharArray());
loop--;
}
}
else
if((S!=null)&&(S.clientTelnetMode(Session.TELNET_MXP)))
{
buf.delete(loop,loop+1);
buf.insert(loop,"<".toCharArray());
loop+=3;
}
}
break;
case '^':
{
if((loop<buf.length()-1)&&(S!=null))
{
int colorID = S.getColor( buf.charAt(loop+1) );
if (colorID != -1)
{
String colorEscStr = S.makeEscape(colorID);
int csl=0;
if (colorEscStr != null)
{
csl = colorEscStr.length();
if (csl > 0)
buf.replace(loop,loop+2 ,colorEscStr);
}
if (csl == 0)
{
// remove the color code
buf.deleteCharAt(loop);
buf.deleteCharAt(loop);
loop-=1;
}
else
if((colorID<('0'))||(colorID>('9')))
{
// begin MXP tags
if(buf.charAt(loop)=='<')
{
int tagStart=loop;
while(loop<(buf.length()-1))
{
if((buf.charAt(loop)!='^')||(buf.charAt(loop+1)!='>'))
{
loop++;
if(loop>=(buf.length()-1))
{
loop=tagStart;
break;
}
}
else
if((S==null)||(!S.clientTelnetMode(Session.TELNET_MXP)))
{
buf.delete(tagStart,loop+2);
loop=tagStart-1;
break;
}
else
{
if(wrap>0)len+=(loop-tagStart);
loop--;
break;
}
}
}
else
{
loop+=csl-1; // already processed 1 char
if(wrap>0)len+=csl; // does not count for any length
}
}
else
{
loop--;
if(wrap>0)len+=csl; // does not count for any length
}
}
}
break;
}
default:
if((firstAlpha < 0)&&(Character.isLetter(buf.charAt(loop))))
firstAlpha = loop;
break;
}
loop++;
}
if((len<buf.length())
&&(loop!=lastSp)
&&(lastSp>=0)
&&(loop>=0)
&&(loop<buf.length())
&&(buf.charAt(loop)!=13)
&&(buf.charAt(loop)!=10))
{
if(buf.charAt(lastSp+1)==' ')
{
buf.setCharAt(lastSp,(char)13);
buf.setCharAt(lastSp+1,(char)10);
}
else
{
buf.setCharAt(lastSp,(char)13);
buf.insert(lastSp,(char)10);
}
loop=lastSp+2;
}
if(wrap>0)len=loop+wrap;
}
if(firstAlpha<0) firstAlpha=0;
if(firstAlpha<buf.length())
buf.setCharAt(firstAlpha,Character.toUpperCase(buf.charAt(firstAlpha)));
if ((S!=null)&&(S.currentColor() != ('N'))&&(S.clientTelnetMode(Session.TELNET_ANSI)))
buf.append(S.makeEscape('N'));
/* fabulous debug code
for(int i=0;i<buf.length();i+=25)
{
for(int x=0;x<25;x++)
{
if((i+x)<buf.length())
{
char c=buf.charAt(i+x);
if((c!='\r')&&(c!='\n'))
System.out.print(c);
else
System.out.print("?");
}
}
System.out.print(" ");
for(int x=0;x<25;x++)
{
if((i+x)<buf.length())
{
int c=(int)buf.charAt(i+x);
int a=c/16;
int b=c%16;
System.out.print(("0123456789ABCDEF").charAt(a));
System.out.print(("0123456789ABCDEF").charAt(b));
}
}
System.out.print(" \n");
}
//*/
return buf.toString();
}
public StringBuffer simpleInFilter(StringBuffer input, boolean allowMXP)
{
if(input==null) return null;
int x=0;
while(x<input.length())
{
char c=input.charAt(x);
if(c=='\'')
input.setCharAt(x,'`');
else
if((c=='^')&&(x<(input.length()-1))&&(!allowMXP))
{
switch(input.charAt(x+1))
{
case '<':
case '>':
case '&':
input.deleteCharAt(x);
break;
}
}
else
if(c==8)
{
String newStr=input.toString();
if(x==0)
input=new StringBuffer(newStr.substring(x+1));
else
{
input=new StringBuffer(newStr.substring(0,x-1)+newStr.substring(x+1));
x--;
}
x--;
}
x++;
}
return new StringBuffer(input.toString());
}
public String fullInFilter(String input, boolean allowMXP)
{
if(input==null) return null;
StringBuffer buf=new StringBuffer(input);
for(int i=0;i<buf.length();i++)
{
switch(buf.charAt(i))
{
case (char)10:
buf.setCharAt(i,'r');
buf.insert(i,'\\');
break;
case (char)13:
buf.setCharAt(i,'n');
buf.insert(i,'\\');
break;
}
}
return simpleInFilter(buf,allowMXP).toString();
}
public String safetyFilter(String s)
{
StringBuffer s1=new StringBuffer(s);
int x=-1;
while((++x)<s1.length())
{
if(s1.charAt(x)=='\r')
{
s1.deleteCharAt(x);
x--;
}
else
if(s1.charAt(x)=='\n')
{
s1.setCharAt(x,'\\');
s1.insert(x+1,'n');
x++;
}
else
if(s1.charAt(x)=='\'')
s1.setCharAt(x,'`');
}
return s1.toString();
}
}