diff --git a/src/java/com/threerings/crowd/data/PlaceObject.java b/src/java/com/threerings/crowd/data/PlaceObject.java index 9f36c4f1f..bd9b6718b 100644 --- a/src/java/com/threerings/crowd/data/PlaceObject.java +++ b/src/java/com/threerings/crowd/data/PlaceObject.java @@ -26,8 +26,11 @@ import java.util.Iterator; import com.threerings.util.Name; import com.threerings.presents.dobj.DObject; +import com.threerings.presents.dobj.DObjectManager; import com.threerings.presents.dobj.DSet; +import com.threerings.presents.dobj.MessageEvent; import com.threerings.presents.dobj.OidList; +import com.threerings.presents.server.LocalDObjectMgr; import com.threerings.crowd.Log; import com.threerings.crowd.chat.data.SpeakMarshaller; @@ -54,14 +57,33 @@ public class PlaceObject extends DObject // AUTO-GENERATED: FIELDS END /** - * Exists solely to make calls into the manager look sensible: + * Exists solely to make calls into the client's DObjManager look sensible: *
_plobj.manager.invoke("someMethod", args);
*/ public class ManagerCaller { - public void invoke (String method, Object ... args) { - postMessage(method, args); + + public ManagerCaller () + { + // Avoid NPE boochery if we're in singleplayer mode in yohoho: + // It turns out that GameController posts events directly to the queue + // of the DObjectManager of the GameObject, which is in this case the + // DObjectManager instead of the ClientDObjectMgr, so the sourceOid is + // unchanged, leading to the nasty problem of caller being null as the + // message was not actually received from any connected outside client. + DObjectManager clomgr = LocalDObjectMgr.clomgr; + if (clomgr != null) { + _mgr = clomgr; + } else { + _mgr = PlaceObject.this.getManager(); + } } + + public void invoke (String method, Object ... args) { + _mgr.postEvent(new MessageEvent(_oid, method, args)); + } + + protected DObjectManager _mgr; } /** diff --git a/src/java/com/threerings/presents/client/Client.java b/src/java/com/threerings/presents/client/Client.java index 9fb8dd5b1..1974fbf7b 100644 --- a/src/java/com/threerings/presents/client/Client.java +++ b/src/java/com/threerings/presents/client/Client.java @@ -37,6 +37,7 @@ import com.threerings.presents.net.BootstrapData; import com.threerings.presents.net.Credentials; import com.threerings.presents.net.PingRequest; import com.threerings.presents.net.PongResponse; +import com.threerings.presents.server.LocalDObjectMgr; /** * Through the client object, a connection to the system is established and maintained. The client @@ -619,6 +620,7 @@ public class Client // clear out our references _comm = null; _omgr = null; + LocalDObjectMgr.clomgr = null; _clobj = null; _cloid = -1; _standalone = false; diff --git a/src/java/com/threerings/presents/server/LocalDObjectMgr.java b/src/java/com/threerings/presents/server/LocalDObjectMgr.java index 2c0817214..788e50b64 100644 --- a/src/java/com/threerings/presents/server/LocalDObjectMgr.java +++ b/src/java/com/threerings/presents/server/LocalDObjectMgr.java @@ -45,7 +45,7 @@ public class LocalDObjectMgr extends PresentsDObjectMgr */ public DObjectManager getClientDObjectMgr (final int clientOid) { - return new DObjectManager() { + clomgr = new DObjectManager() { public boolean isManager (DObject object) { return LocalDObjectMgr.this.isManager(object); } @@ -65,6 +65,7 @@ public class LocalDObjectMgr extends PresentsDObjectMgr LocalDObjectMgr.this.removedLastSubscriber(obj, deathWish); } }; + return clomgr; } // documentation inherited @@ -92,4 +93,6 @@ public class LocalDObjectMgr extends PresentsDObjectMgr // accounting data EventQueue.invokeLater(unit); } + + public static DObjectManager clomgr = null; }