package com.planet_ink.coffee_mud.WebMacros; import com.planet_ink.coffee_web.http.HTTPException; import com.planet_ink.coffee_web.http.HTTPMethod; import com.planet_ink.coffee_web.http.MIMEType; import com.planet_ink.coffee_web.http.MultiPartData; import com.planet_ink.coffee_web.interfaces.*; import com.planet_ink.coffee_web.util.CWThread; import com.planet_ink.coffee_web.util.CWConfig; import com.planet_ink.coffee_mud.WebMacros.interfaces.*; import com.planet_ink.coffee_mud.core.interfaces.*; import com.planet_ink.coffee_mud.core.*; import com.planet_ink.coffee_mud.core.CMSecurity.DbgFlag; import com.planet_ink.coffee_mud.core.collections.*; 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.Libraries.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 com.planet_ink.coffee_mud.core.exceptions.*; import java.io.File; import java.io.InputStream; import java.net.InetAddress; import java.util.*; /* Copyright 2002-2019 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 StdWebMacro implements WebMacro { @Override public String ID() { return name(); } @Override public String name() { return "UNKNOWN"; } @Override public boolean isAWebPath() { return false; } @Override public boolean preferBinary() { return false; } @Override public boolean isAdminMacro() { return false; } @Override public CMObject newInstance() { return this; } @Override public void initializeClass() { } @Override public CMObject copyOf() { return this; } @Override public byte[] runBinaryMacro(final HTTPRequest httpReq, final String parm, final HTTPResponse httpResp) throws HTTPServerException { return runMacro(httpReq,parm, null).getBytes(); } @Override public String runMacro(final HTTPRequest httpReq, final String parm, final HTTPResponse httpResp) throws HTTPServerException { return "[Unimplemented macro!]"; } @Override public int compareTo(final CMObject o) { return CMClass.classID(this).compareToIgnoreCase(CMClass.classID(o)); } protected StringBuffer colorwebifyOnly(final StringBuffer s) { if(s==null) return null; int i=0; final String[] lookup=CMLib.color().standardHTMLlookups(); while(i<s.length()) { if(s.charAt(i)=='^') { if(i<(s.length()-1)) { final char c=s.charAt(i+1); //TODO: handle ~ and # here? final String code=lookup[c]; if(code!=null) { s.delete(i,i+2); if(code.startsWith("<")) { s.insert(i,code+">"); i+=code.length(); } else { s.insert(i,code); i+=code.length()-1; } } else if(c=='?') { s.delete(i,i+2); s.insert(i,"</FONT>"); i+=7; } } } i++; } return s; } protected StringBuffer webify(StringBuffer s) { if(s==null) return null; int i=0; while(i<s.length()) { switch(s.charAt(i)) { case '\n': case '\r': if((i<s.length()-1) &&(s.charAt(i+1)!=s.charAt(i)) &&((s.charAt(i+1)=='\r')||(s.charAt(i+1)=='\n'))) { s.delete(i,i+2); s.insert(i,"<BR>"); i+=3; } else { s.delete(i,i+1); s.insert(i,"<BR>"); i+=3; } break; case ' ': s.setCharAt(i,'&'); s.insert(i+1,"nbsp;"); i+=5; break; case '>': s.setCharAt(i,'&'); s.insert(i+1,"gt;"); i+=3; break; case '<': s.setCharAt(i,'&'); s.insert(i+1,"lt;"); i+=3; break; } i++; } s=colorwebifyOnly(s); return s; } protected String clearWebMacros(final String s) { return CMLib.webMacroFilter().clearWebMacros(s); } protected String clearWebMacros(final StringBuffer s) { return CMLib.webMacroFilter().clearWebMacros(s); } protected StringBuilder helpHelp(final StringBuilder s) { return helpHelp(s, 70); } protected StringBuilder helpHelp(final String s) { return helpHelp(new StringBuilder(s), 70); } protected StringBuilder helpHelp(StringBuilder s, final int limit) { if(s!=null) { final String[] lookup=CMLib.color().standardHTMLlookups(); s=new StringBuilder(s.toString()); int x=0; int count=0; x=0; int lastSpace=0; //TODO: limit should adjust or lastspace should -- something is wrong RIGHT HERE! while((x>=0)&&(x<s.length())) { count++; switch(s.charAt(x)) { case '\\': if(x<s.length()-1) { if(s.charAt(x+1)=='n') { s.delete(x, x+2); s.insert(x, " <BR>"); lastSpace=x; } } break; case '\n': if(x<s.length()-1) { if(s.charAt(x+1)=='\r') { s.delete(x, x+2); s.insert(x, " <BR>"); } else { s.delete(x, x+1); s.insert(x, " <BR>"); } lastSpace=x; } break; case '\r': if(x<s.length()-1) { if(s.charAt(x+1)=='\n') { s.delete(x, x+2); s.insert(x, " <BR>"); } else { s.delete(x, x+1); s.insert(x, " <BR>"); } lastSpace=x; } break; case ' ': lastSpace=x; break; case '<': if((x<=s.length()-4) &&(s.substring(x,x+4).equalsIgnoreCase("<BR>"))) { count=0; x=x+3; lastSpace=x+4; } else { s.setCharAt(x,'&'); s.insert(x+1,"lt;"); x+=3; } break; case '-': if((x>4) &&(s.charAt(x-1)=='-') &&(s.charAt(x-2)=='-') &&(s.charAt(x-3)=='-')) { count=0; lastSpace=x; } break; case '!': if((x>4) &&(s.charAt(x-1)==' ') &&(s.charAt(x-2)==' ') &&(s.charAt(x-3)==' ')) { count=0; lastSpace=x; } else if((x<s.length()-10) // remove music &&(s.charAt(x+1)=='!') &&((s.substring(x+2,x+7).equalsIgnoreCase("sound")) ||(s.substring(x+2,x+7).equalsIgnoreCase("music")))) { final int x1=s.indexOf("(",x+7); final int y1=s.indexOf(")",x+7); if((x1>=0)&&(y1>=x1)) { s.delete(x,y1+1); x--; } } break; case '^': if(x<(s.length()-1)) { char c=s.charAt(x+1); if(c=='?') c='w'; final String code=lookup[c]; if(code!=null) { s.delete(x,x+2); if(code.startsWith("<")) { s.insert(x,code+">"); x+=code.length(); } else { s.insert(x,code); x+=code.length()-1; } } count--; } break; } if(count==limit) { //int brx=s.indexOf("<BR>",lastSpace); //if((brx<0)||(brx>lastSpace+12)) s.replace(lastSpace,lastSpace+1,"<BR>"); lastSpace=lastSpace+4; x=lastSpace; count=0; } else x++; } return s; } return new StringBuilder(""); } protected PairSVector<String,String> parseOrderedParms(final String parm, final boolean preserveCase) { final PairSVector<String,String> requestParms=new PairSVector<String,String>(); if((parm!=null)&&(parm.length()>0)) { int lastDex=0; CharSequence varSeq=null; for(int i=0;i<parm.length();i++) { switch(parm.charAt(i)) { case '\\': i++; break; case '&': { if(varSeq==null) { if(preserveCase) requestParms.add(parm.substring(lastDex,i),parm.substring(lastDex,i)); else requestParms.add(parm.substring(lastDex,i).toUpperCase().trim(),parm.substring(lastDex,i).trim()); } else { if(preserveCase) requestParms.add(varSeq.toString(),parm.substring(lastDex,i)); else requestParms.add(varSeq.toString().trim().toUpperCase(),parm.substring(lastDex,i).trim()); } lastDex=i+1; varSeq=null; break; } case '=': { if(varSeq==null) { varSeq=parm.subSequence(lastDex,i); lastDex=i+1; } break; } } } final int i=parm.length(); if(varSeq==null) { if(preserveCase) requestParms.add(parm.substring(lastDex,i),parm.substring(lastDex,i)); else requestParms.add(parm.substring(lastDex,i).trim().toUpperCase(),parm.substring(lastDex,i).trim()); } else { if(preserveCase) requestParms.add(varSeq.toString(),parm.substring(lastDex,i)); else requestParms.add(varSeq.toString().trim().toUpperCase(),parm.substring(lastDex,i).trim()); } } return requestParms; } protected String safeIncomingfilter(final String buf) { if(buf==null) return null; if(buf.length()==0) return ""; return CMLib.coffeeFilter().simpleInFilter(new StringBuilder(buf)); } protected String htmlIncomingFilter(final String buf) { return htmlIncomingFilter(new StringBuffer(buf)).toString(); } protected StringBuffer htmlIncomingFilter(final StringBuffer buf) { int loop=0; while(buf.length()>loop) { if((buf.charAt(loop)=='&') &&(loop<buf.length()-3)) { int endloop=loop+1; while((endloop<buf.length())&&(endloop<loop+10)&&(buf.charAt(endloop)!=';')) endloop++; if(endloop<buf.length()) { final String s=buf.substring(loop,endloop+1); if(s.equalsIgnoreCase(">")) { buf.setCharAt(loop,'>'); buf.delete(loop+1,endloop+1); } else if(s.equalsIgnoreCase("<")) { buf.setCharAt(loop,'<'); buf.delete(loop+1,endloop+1); } else if(s.equalsIgnoreCase("&")) { buf.setCharAt(loop,'&'); buf.delete(loop+1,endloop+1); } else if(s.equalsIgnoreCase(""")) { buf.setCharAt(loop,'\"'); buf.delete(loop+1,endloop+1); } } } loop++; } return buf; } protected String htmlOutgoingFilter(final String buf) { return htmlOutgoingFilter(new StringBuffer(buf)).toString(); } protected StringBuffer htmlOutgoingFilter(final StringBuffer buf) { int loop=0; while(buf.length()>loop) { switch(buf.charAt(loop)) { case '>': buf.delete(loop,loop+1); buf.insert(loop,">".toCharArray()); loop+=3; break; case '"': buf.delete(loop,loop+1); buf.insert(loop,""".toCharArray()); loop+=5; break; case '&': if((loop+3>=buf.length()) ||((!buf.substring(loop,loop+3).equalsIgnoreCase("lt;")) &&(!buf.substring(loop,loop+3).equalsIgnoreCase("amp;")) &&(!buf.substring(loop,loop+3).equalsIgnoreCase("quot;")) &&(!buf.substring(loop,loop+3).equalsIgnoreCase("gt;")))) { buf.delete(loop,loop+1); buf.insert(loop,"&".toCharArray()); loop+=4; } else loop++; break; case '<': buf.delete(loop,loop+1); buf.insert(loop,"<".toCharArray()); loop+=3; break; default: loop++; } } return buf; } protected byte[] getHTTPFileData(final HTTPRequest httpReq, final String file) throws HTTPException { if(Thread.currentThread() instanceof CWThread) { final CWConfig config=((CWThread)Thread.currentThread()).getConfig(); final HTTPRequest newReq=new HTTPRequest() { final Hashtable<String,String> params=new XHashtable<String,String>(httpReq.getUrlParametersCopy()); @Override public String getHost() { return httpReq.getHost(); } @Override public String getUrlPath() { return file; } @Override public String getFullRequest() { return httpReq.getMethod().name() + " " + getUrlPath(); } @Override public String getUrlParameter(final String name) { return params.get(name.toLowerCase()); } @Override public Map<String, String> getUrlParametersCopy() { return new XHashtable<String, String>(params); } @Override public boolean isUrlParameter(final String name) { return params.containsKey(name.toLowerCase()); } @Override public Set<String> getUrlParameters() { return params.keySet(); } @Override public HTTPMethod getMethod() { return httpReq.getMethod(); } @Override public String getHeader(final String name) { return httpReq.getHeader(name); } @Override public InetAddress getClientAddress() { return httpReq.getClientAddress(); } @Override public int getClientPort() { return httpReq.getClientPort(); } @Override public InputStream getBody() { return httpReq.getBody(); } @Override public String getCookie(final String name) { return httpReq.getCookie(name); } @Override public Set<String> getCookieNames() { return httpReq.getCookieNames(); } @Override public List<MultiPartData> getMultiParts() { return httpReq.getMultiParts(); } @Override public double getSpecialEncodingAcceptability(final String type) { return httpReq.getSpecialEncodingAcceptability(type); } @Override public String getFullHost() { return httpReq.getFullHost(); } @Override public List<long[]> getRangeAZ() { return httpReq.getRangeAZ(); } @Override public void addFakeUrlParameter(final String name, final String value) { params.put(name.toLowerCase(), value); } @Override public void removeUrlParameter(final String name) { params.remove(name.toLowerCase()); } @Override public Map<String, Object> getRequestObjects() { return httpReq.getRequestObjects(); } @Override public float getHttpVer() { return httpReq.getHttpVer(); } @Override public String getQueryString() { return httpReq.getQueryString(); } }; final DataBuffers data=config.getFileGetter().getFileData(newReq); return data.flushToBuffer().array(); } return new byte[0]; } protected File grabFile(final HTTPRequest httpReq, String filename) { if(Thread.currentThread() instanceof CWThread) { filename=filename.replace(File.separatorChar,'/'); if (!filename.startsWith("/")) filename = '/' + filename; final String file=filename; final CWConfig config=((CWThread)Thread.currentThread()).getConfig(); final HTTPRequest newReq=new HTTPRequest() { public final Hashtable<String,String> params=new XHashtable<String,String>(httpReq.getUrlParametersCopy()); @Override public String getHost() { return httpReq.getHost(); } @Override public String getUrlPath() { return file; } @Override public String getFullRequest() { return httpReq.getMethod().name() + " " + getUrlPath(); } @Override public String getUrlParameter(final String name) { return params.get(name.toUpperCase()); } @Override public boolean isUrlParameter(final String name) { return params.containsKey(name.toUpperCase()); } @Override public Map<String, String> getUrlParametersCopy() { return new XHashtable<String, String>(params); } @Override public Set<String> getUrlParameters() { return params.keySet(); } @Override public HTTPMethod getMethod() { return httpReq.getMethod(); } @Override public String getHeader(final String name) { return httpReq.getHeader(name); } @Override public InetAddress getClientAddress() { return httpReq.getClientAddress(); } @Override public int getClientPort() { return httpReq.getClientPort(); } @Override public InputStream getBody() { return httpReq.getBody(); } @Override public String getCookie(final String name) { return httpReq.getCookie(name); } @Override public Set<String> getCookieNames() { return httpReq.getCookieNames(); } @Override public List<MultiPartData> getMultiParts() { return httpReq.getMultiParts(); } @Override public double getSpecialEncodingAcceptability(final String type) { return httpReq.getSpecialEncodingAcceptability(type); } @Override public String getFullHost() { return httpReq.getFullHost(); } @Override public List<long[]> getRangeAZ() { return httpReq.getRangeAZ(); } @Override public void addFakeUrlParameter(final String name, final String value) { params.put(name.toUpperCase(), value); } @Override public void removeUrlParameter(final String name) { params.remove(name.toUpperCase()); } @Override public Map<String, Object> getRequestObjects() { return httpReq.getRequestObjects(); } @Override public float getHttpVer() { return httpReq.getHttpVer(); } @Override public String getQueryString() { return httpReq.getQueryString(); } }; return config.getFileGetter().createFile(newReq,config.getFileGetter().assembleFilePath(newReq)); } return null; } protected java.util.Map<String,String> parseParms(final String parm) { final Hashtable<String,String> requestParms=new Hashtable<String,String>(); final PairSVector<String,String> requestParsed = parseOrderedParms(parm,false); for(final Pair<String,String> P : requestParsed) requestParms.put(P.first,P.second); return requestParms; } protected java.util.Map<String,String> parseParms(final String parm, final boolean preserveCase) { final Hashtable<String,String> requestParms=new Hashtable<String,String>(); final PairSVector<String,String> requestParsed = parseOrderedParms(parm,preserveCase); for(final Pair<String,String> P : requestParsed) requestParms.put(P.first,P.second); return requestParms; } public String L(final String str, final String ... xs) { return CMLib.lang().fullSessionTranslation(str, xs); } }