}
@Override
public void setNick(String oldname, String username) {
User user;
try {
database.startTransaction();
// maybe this should not "fix" the errors but throw an exception!
// then again we send the username back to the client, so is prob ok
username = LobbyCom.checkUsername(username);
if (oldname.equals(username) || (oldname.toLowerCase().startsWith("guest") && username.length()==0)) {
// should never happen
throw new IllegalArgumentException("new name same as old name: "+oldname);
}
if (username.toLowerCase().startsWith("guest")) {
throw new IllegalArgumentException("can not start your nick with guest: "+username );
}
if (trimToLetters(username.toLowerCase()).endsWith("bot")) {
throw new IllegalArgumentException("can not end your nick with bot: "+username );
}
if (username.toLowerCase().endsWith("resigned")) {
throw new IllegalArgumentException("can not end your nick with resigned: "+username );
}
if (username.toLowerCase().equals("null")) {
throw new IllegalArgumentException("you can not call yourself: "+username );
}
if (username.indexOf('\n') >= 0 || username.indexOf('\r') >= 0 || username.indexOf('\t') >= 0) {
throw new IllegalArgumentException("you can not have a that symbol in your name: "+username );
}
if (username.length()!=0 && username.length() < 4) {
throw new IllegalArgumentException("username must be at least 4 chars: "+username);
}
if (username.length()!=0 && username.length() > 45) { // 45 is length of field in JPADB
throw new IllegalArgumentException("username is too long, must be less then 45 chars: "+username);
}
if (username.length()!=0 && database.getUser(username)!=null) {
// error: an account is already registered with this name
// error: or a guest has joined a game with this name
// error: a guest is connected with this name
throw new IllegalArgumentException("this user is already in the database: "+username);
}
user = database.getUser(oldname);
if (user==null) {
throw new IllegalArgumentException("user with name \""+oldname+"\" not found");
}
user.setName(username.length()==0?null:username);
database.saveUser(user);
}
finally {
database.endTransaction();
}
// everything went ok with renaming, now we need to send out 3 commands
// 1) COMMAND_LOGIN_OK/COMMAND_LOGOUT_OK
// 2) COMMAND_ADD_OR_UPDATE_GAME and COMMAND_RENAME_PLAYER
// and we need to make sure it is in this order otherise the client game action buttons may get wrong option
Map responce = new HashMap();
responce.put("username", user.getName() ); // username sent server->client not encrypted
responce.put("userType", user.getType() );
Collection<LobbySession> sessions = server.getLobbySession(oldname);
for (LobbySession session:sessions) {
session.setUser(user.getName());
// TODO what exactly is the difference between these 2 commands???
if (username.length()==0) {
send( session,ProtoAccess.COMMAND_LOGOUT_OK, responce );
}
else {
send( session,ProtoAccess.COMMAND_LOGIN_OK, responce );
}
}
// these are the games that the user is currently in or is watching
Set<LobbySession> others = new HashSet();
// this is the games that the user has joined
for (GameRoom gm: user.getGames() ) {
ServerGame serverGame = runningGames.get(gm.getId());
if (serverGame!=null) {
serverGame.midgameLogin( oldname, user.getName() );
others.addAll( serverGame.getAllClients() );
}
gameChanged(gm);
}
for (LobbySession session:sessions) for (ServerGame gm: session.playingOrWatchingGame ) {
// put together a list of everyone watching any of this users games
others.addAll( gm.getAllClients() );
}
Map send = new HashMap();
send.put("oldName", oldname );
send.put("newName", user.getName() );
send.put("userType", user.getType() );
for (LobbySession other: others) {
// we need to send this even to ourselves as we need to be renamed there too
send(other, ProtoAccess.COMMAND_RENAME_PLAYER, send);
}
}