Java tutorial
/* * Morphy Open Source Chess Server * Copyright (C) 2008-2011, 2017 http://code.google.com/p/morphy-chess-server/ * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package morphy.command; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.TimeZone; import org.apache.commons.lang.StringUtils; import morphy.command.VariablesCommand.variables; import morphy.game.request.MatchRequest; import morphy.game.request.PartnershipRequest; import morphy.game.request.Request; import morphy.game.style.StyleInterface; import morphy.service.RequestService; import morphy.user.UserInfoList; import morphy.user.UserSession; import morphy.utils.john.TimeZoneUtils; public class SetCommand extends AbstractCommand { public class BadValueException extends Exception { private static final long serialVersionUID = 1L; private String varname; public BadValueException(String variable) { this.varname = variable; } @Override public String getMessage() { return "Bad value given for variable \"" + varname + "\"."; } } public SetCommand() { super("Set"); } public void process(String arguments, UserSession userSession) { int pos = arguments.indexOf(" "); if (!arguments.startsWith("busy") && pos == -1) { userSession.send(getContext().getUsage()); return; } if (arguments.equals("busy")) { pos = arguments.length(); } String setWhat = arguments.substring(0, pos).trim(); String message = arguments.substring(pos).trim(); variables[] varr = variables.values(); java.util.Arrays.sort(varr); variables[] v = findAllMatches(varr, setWhat); //System.out.println(java.util.Arrays.toString(v)); if (StringUtils.isNumeric(setWhat)) { // finger notes int val = Integer.parseInt(setWhat); if (val >= 1 && val <= UserInfoList.MAX_NOTES) { List<String> notes = userSession.getUser().getUserInfoLists().get(UserInfoList.notes); if (notes == null) { notes = new ArrayList<String>(UserInfoList.MAX_NOTES); userSession.getUser().getUserInfoLists().put(UserInfoList.notes, notes); } if (notes.size() == 0) { while (notes.size() < 10) { notes.add(""); } } notes.set(val - 1, message); //Plan line 6 changed to 'hi'. //Plan line 6 cleared. String returnmess = (message.equals("") ? "Plan line " + val + " cleared." : "Plan line " + val + " changed to '" + message + "'."); userSession.send(returnmess); return; } else { userSession.send("No such variable \"" + val + "\"."); return; } } else if (setWhat.matches("f[1-9]")) { // var notes } else if (v.length > 0) { // variables if (v.length > 1) { StringBuilder errmess = new StringBuilder("Ambiguous variable \"" + setWhat + "\". Matches: "); for (int i = 0; i < v.length; i++) { variables elem = v[i]; errmess.append(elem.name()); if (i != v.length - 1) errmess.append(" "); } userSession.send(errmess.toString()); return; } if (v.length == 1) { variables var = v[0]; if (var.getType().equals(Integer.class) && !StringUtils.isNumeric(message)) { if (message.equalsIgnoreCase("true")) message = "1"; else if (message.equalsIgnoreCase("false")) message = "0"; else { userSession.send("Bad value given for variable \"" + var.getName() + "\"."); return; } } // no validation for string inputs... morphy.user.UserVars uv = userSession.getUser().getUserVars(); // TODO finish this. String returnmessage = ""; String setOrUnset = (message.equals("1") ? "set" : "unset"); String nowOrNot = (message.equals("1") ? "now" : "not"); String onOrOff = (message.equals("1") ? "on" : "off"); try { switch (var) { case time: if (!StringUtils.isNumeric(message)) throw new BadValueException("time"); returnmessage = "Default time set to " + message + "."; break; case inc: if (!StringUtils.isNumeric(message)) throw new BadValueException("time"); returnmessage = "Default increment set to " + message + "."; break; case rated: if (!is0or1(message)) throw new BadValueException("rated"); if (!userSession.getUser().isRegistered()) returnmessage = "Unregistered users cannot change their rated status."; else returnmessage = "Games will be " + (message.equals("1") ? "rated" : "unrated") + " by default."; break; case open: if (!is0or1(message)) throw new BadValueException("open"); returnmessage = "You are " + (message.equals("1") ? "now open to receive" : "no longer receiving") + " match requests."; break; case tourney: if (!is0or1(message)) throw new BadValueException("tourney"); returnmessage = "Your tournament variable is " + (message.equals("1") ? "now" : "no longer") + " set."; break; case provshow: if (!is0or1(message)) throw new BadValueException("provshow"); returnmessage = "Provisional or inactive ratings will now" + (message.equals("0") ? " not" : "") + " be marked."; break; case autoflag: if (!is0or1(message)) throw new BadValueException("autoflag"); returnmessage = "Auto-flagging " + (message.equals("1") ? "enabled" : "disabled") + "."; break; case minmovetime: if (!is0or1(message)) throw new BadValueException("minmovetime"); returnmessage = "You will" + (message.equals("1") ? "" : " not") + " request minimum move time when games start."; break; case myprivate: if (!is0or1(message)) throw new BadValueException("private"); returnmessage = "Your games will" + (message.equals("1") ? "" : " not") + " be private."; break; case jprivate: if (!userSession.getUser().isRegistered()) returnmessage = "Only registered players may keep a journal."; else returnmessage = "Your journal will" + (message.equals("1") ? "" : " not") + " be private."; if (!is0or1(message)) throw new BadValueException("jprivate"); break; case automail: if (!userSession.getUser().isRegistered()) returnmessage = "Unregistered players may not have games mailed."; else returnmessage = ""; if (!is0or1(message)) throw new BadValueException("automail"); break; case pgn: if (!is0or1(message)) throw new BadValueException("pgn"); returnmessage = "Games will now be mailed to you in " + (message.equals("1") ? "PGN" : "server format") + "."; break; case mailmess: if (!userSession.getUser().isRegistered()) returnmessage = "Unregistered players may not receive messages."; else returnmessage = ""; if (!is0or1(message)) throw new BadValueException("mailmess"); break; case messreply: if (!userSession.getUser().isRegistered()) returnmessage = "Unregistered players cannot use this variable."; else returnmessage = ""; if (!is0or1(message)) throw new BadValueException("messreply"); break; case unobserve: if (message.equals("1")) returnmessage = "You will now only auto unobserve on matches."; if (message.equals("2")) returnmessage = "You will now only auto unobserve on examine."; if (message.equals("3")) returnmessage = "You will not auto unobserve."; if (!message.matches("[1|2|3]")) throw new BadValueException("unobserve"); break; case shout: if (!is0or1(message)) throw new BadValueException("shout"); returnmessage = "You will " + nowOrNot + " hear shouts."; break; case cshout: if (!is0or1(message)) throw new BadValueException("cshout"); returnmessage = "You will " + nowOrNot + " hear cshouts."; break; case kibitz: if (!is0or1(message)) throw new BadValueException("kibitz"); returnmessage = "You will " + nowOrNot + " hear kibitzes."; break; case kiblevel: if (Integer.parseInt(message) < 0 || Integer.parseInt(message) >= 10000) throw new BadValueException("kiblevel"); returnmessage = "Kibitz level now set to " + message + "."; break; case tell: if (!is0or1(message)) throw new BadValueException("tell"); if (message.equals("0")) returnmessage = "You will not hear direct tells from unregistered users."; if (message.equals("1")) returnmessage = "You will now hear direct tells from all users."; break; case ctell: if (!is0or1(message)) throw new BadValueException("ctell"); if (message.equals("0")) returnmessage = "You will not hear channel tells from unregistered users."; if (message.equals("1")) returnmessage = "You will now hear channel tells from all users."; break; case chanoff: if (!is0or1(message)) throw new BadValueException("chanoff"); returnmessage = "You will " + nowOrNot + " hear channel tells."; break; case silence: if (!is0or1(message)) throw new BadValueException("silence"); returnmessage = "You will now" + (message.equals("0") ? " not" : "") + " play games in silence."; break; case echo: if (!is0or1(message)) throw new BadValueException("echo"); returnmessage = "You will now" + (message.equals("0") ? " not" : "") + " hear communications echoed."; break; case pin: if (!is0or1(message)) throw new BadValueException("pin"); returnmessage = "You will " + nowOrNot + " hear logins/logouts."; break; case notifiedby: if (!is0or1(message)) throw new BadValueException("notifiedby"); returnmessage = "You will " + nowOrNot + " hear if people notify you, but you don't notify them."; break; case availinfo: if (!is0or1(message)) throw new BadValueException("availinfo"); returnmessage = "You will" + (message.equals("0") ? " not" : "") + " receive info on who is available to play."; break; case seek: if (!is0or1(message)) throw new BadValueException("seek"); returnmessage = "You will " + nowOrNot + " see seek ads."; break; case bugopen: if (!is0or1(message)) throw new BadValueException("bugopen"); returnmessage = "You are " + nowOrNot + " open for bughouse."; break; case tolerance: if (!message.matches("[1|2|3|4|5]")) throw new BadValueException("tolerance"); returnmessage = "Tolerance level set to " + message + "."; break; case bell: if (!is0or1(message)) throw new BadValueException("bell"); returnmessage = "Bell " + onOrOff + "."; break; case availmin: case availmax: if (!is0or1(message)) throw new BadValueException(var.name()); if (Integer.parseInt(uv.getVariables().get("availmin")) > Integer .parseInt(uv.getVariables().get("availmax"))) returnmessage = "You can't set availmin to more than availmax."; else returnmessage = "You will be notified of availability with blitz ratings " + uv.getVariables().get("availmin") + " - " + uv.getVariables().get("availmax") + "."; break; case gin: if (!is0or1(message)) throw new BadValueException("gin"); returnmessage = "You will " + nowOrNot + " hear game results."; break; case showownseek: if (!is0or1(message)) throw new BadValueException("showownseek"); returnmessage = "You will " + nowOrNot + " see your own seeks."; break; case examine: if (!is0or1(message)) throw new BadValueException("examine"); returnmessage = "You will now" + (message.equals("0") ? " not" : "") + " enter examine mode after a game."; break; case noescape: if (!is0or1(message)) throw new BadValueException("noescape"); returnmessage = "You will" + (message.equals("0") ? " not" : "") + " request noescape when games start."; break; case style: if (!StringUtils.isNumeric(message)) throw new BadValueException("style"); int style = Integer.parseInt(message); if (style < 1 || style > 13) throw new BadValueException("style"); returnmessage = "Style " + message + " set."; break; case flip: if (!is0or1(message)) throw new BadValueException("flip"); returnmessage = "Flip " + onOrOff + "."; break; case highlight: if (Integer.parseInt(message) < 1 || Integer.parseInt(message) > 15) throw new BadValueException("highlight"); returnmessage = "Highlight is now style " + message + "."; break; case width: if (Integer.parseInt(message) < 32 || Integer.parseInt(message) > 240) throw new BadValueException("width"); returnmessage = "Width set to " + message + "."; break; case height: if (Integer.parseInt(message) < 5 || Integer.parseInt(message) > 240) throw new BadValueException("width"); returnmessage = "Height set to " + message + "."; break; case ptime: if (!is0or1(message)) throw new BadValueException("ptime"); if (message.equals("0")) returnmessage = "Your prompt will now not show the time."; if (message.equals("1")) returnmessage = "Your prompt will now show the time (SERVER)."; break; case tzone: { message = message.toUpperCase(); TimeZone tz = TimeZoneUtils.getTimeZone(message); if (message.equals("GMT") && tz.equals(TimeZone.getTimeZone("GMT"))) returnmessage = "Invalid timezone - see 'help timezones'"; returnmessage = "Timezone set to " + message.toUpperCase() + " (GMT ...)."; break; } case lang: { String[] arr = getDistinctLocalesByLanguage(); java.util.Arrays.sort(arr); int index = java.util.Arrays.binarySearch(arr, message); if (index != Math.abs(index)) { throw new BadValueException("lang"); } else { returnmessage = "Language set to " + message + "."; } break; } case notakeback: if (!is0or1(message)) throw new BadValueException("notakeback"); returnmessage = "You will " + nowOrNot + " allow takebacks."; break; case myinterface: returnmessage = ""; break; case prompt: returnmessage = "Prompt set to \"" + message + "\""; break; case busy: { if (message.equals("")) { returnmessage = "Your \"busy\" string was cleared."; break; } else { returnmessage = "Your \"busy\" string was set to \"" + message + "\"."; break; } } default: returnmessage = var.getName() + " " + setOrUnset + "."; } uv.update(setWhat.toLowerCase(), message); if (var == variables.style) { int style = Integer.parseInt(message); StyleInterface si = null; si = getStyle(style); if (si == null) { userSession.send("That style is not available at this time, please try again later."); } else { userSession.getUser().getUserVars().setStyle(si); } } RequestService rq = RequestService.getInstance(); if (var == VariablesCommand.variables.open && message.equals("0")) { final String myUsername = userSession.getUser().getUserName(); List<Request> list = rq.findAllToRequestsByType(userSession, MatchRequest.class); if (list != null) { for (Request r : list) { r.getFrom().send(String.format( "%s, whom you were challenging, has become unavailable for matches.\nChallenge to %s withdrawn.", myUsername, myUsername)); rq.removeRequest(r); userSession.send(String.format("Challenge from %s removed.", r.getFrom().getUser().getUserName())); } } } if (var == variables.bugopen && message.equals("0")) { final String myUsername = userSession.getUser().getUserName(); List<Request> list = rq.findAllToRequestsByType(userSession, PartnershipRequest.class); for (Request r : list) { r.getFrom().send(String.format( "%s, whom you were offering a partnership with, has become unavailable for bughouse.\n" + "Partnership offer to %s withdrawn.", myUsername, myUsername)); rq.removeRequest(r); userSession.send(String.format("Partnership offer from %s removed.", r.getFrom().getUser().getUserName())); } } userSession.send(returnmessage); } catch (BadValueException e) { userSession.send(e.getMessage()); } } } else { userSession.send(String.format("No such variable \"%s\".", setWhat)); } } /** Uses reflection */ private StyleInterface getStyle(int styleNum) { try { Class<?> myClass = Class.forName("morphy.game.style.Style" + styleNum); return (StyleInterface) myClass.getMethod("getSingletonInstance").invoke(null); } catch (ClassNotFoundException e) { e.printStackTrace(System.err); } catch (IllegalAccessException e) { e.printStackTrace(System.err); } catch (IllegalArgumentException e) { e.printStackTrace(System.err); } catch (SecurityException e) { e.printStackTrace(System.err); } catch (InvocationTargetException e) { e.printStackTrace(System.err); } catch (NoSuchMethodException e) { e.printStackTrace(System.err); } return null; } private variables[] findAllMatches(variables[] vars, String varname) { java.util.List<variables> arr = new java.util.ArrayList<variables>(); varname = varname.toLowerCase(); for (variables v : vars) { String tmp = v.name().toLowerCase(); if (tmp.indexOf("my") == 0) tmp = tmp.substring(2); if (tmp.startsWith(varname)) { arr.add(v); } } return arr.toArray(new variables[arr.size()]); } private String[] getDistinctLocalesByLanguage() { List<String> list = new ArrayList<String>(); Locale[] arr = Locale.getAvailableLocales(); for (Locale l : arr) { String v = l.getDisplayLanguage(); if (!list.contains(v)) list.add(v); } return list.toArray(new String[list.size()]); } protected boolean is0or1(String in) { return in.equals("1") || in.equals("0"); } }