diff --git a/src/java/com/threerings/presents/server/ClientManager.java b/src/java/com/threerings/presents/server/ClientManager.java
index 58c42ec2b..335ed6712 100644
--- a/src/java/com/threerings/presents/server/ClientManager.java
+++ b/src/java/com/threerings/presents/server/ClientManager.java
@@ -24,7 +24,6 @@ package com.threerings.presents.server;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.logging.Level;
@@ -307,6 +306,23 @@ public class ClientManager
PresentsServer.omgr.destroyObject(clobj.getOid());
}
+ /**
+ * Renames a currently connected client from oldname to newname
+ *
+ * @return true if the client was found and renamed.
+ */
+ protected boolean renameClientObject (Name oldname, Name newname)
+ {
+ ClientObject clobj = _objmap.remove(oldname);
+ if (clobj == null) {
+ log.warning("Requested to rename unmapped client object [username=" + oldname + "].");
+ Thread.dumpStack();
+ return false;
+ }
+ _objmap.put(newname, clobj);
+ return true;
+ }
+
// documentation inherited from interface ClientResolutionListener
public synchronized void clientResolved (Name username, ClientObject clobj)
{
diff --git a/src/java/com/threerings/presents/server/PresentsClient.java b/src/java/com/threerings/presents/server/PresentsClient.java
index cebd42b67..dcec78ddb 100644
--- a/src/java/com/threerings/presents/server/PresentsClient.java
+++ b/src/java/com/threerings/presents/server/PresentsClient.java
@@ -261,6 +261,24 @@ public class PresentsClient
_cmgr.resolveClientObject(username, clr);
}
+ /**
+ * Double Danger: this method is not for general consumption. Like
+ * {@code #setUsername}, this changes the username of the client, but unlike setUsername, it
+ * does it in the existing client object. Care must be taken to ensure that any client or
+ * server code either doesn't map things based on username before this call, or that it's
+ * updated to reflect the change.
+ *
+ * @return - true if the client was successfully renamed, false otherwise
+ */
+ public boolean updateUsername (Name username)
+ {
+ if (_cmgr.renameClientObject(_username, username)) {
+ _username = username;
+ return true;
+ }
+ return false;
+ }
+
/**
* Returns the client object that is associated with this client.
*/