//
// $Id$
//
// ToyBox library - framework for matchmaking networked games
// Copyright (C) 2004 Three Rings Design, Inc., All Rights Reserved
// http://www.gamegardens.com/code/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.toybox.server;

import java.io.File;
import java.util.logging.Level;

import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Guice;

import com.samskivert.jdbc.ConnectionProvider;
import com.samskivert.jdbc.StaticConnectionProvider;
import com.samskivert.util.StringUtil;

import com.threerings.util.Name;

import com.threerings.presents.client.Client;
import com.threerings.presents.dobj.RootDObjectManager;
import com.threerings.presents.net.AuthRequest;
import com.threerings.presents.server.Authenticator;
import com.threerings.presents.server.ClientFactory;
import com.threerings.presents.server.ClientResolver;
import com.threerings.presents.server.InvocationManager;
import com.threerings.presents.server.PresentsClient;
import com.threerings.presents.server.ShutdownManager;

import com.threerings.crowd.data.PlaceConfig;
import com.threerings.crowd.server.CrowdClient;
import com.threerings.crowd.server.CrowdServer;
import com.threerings.crowd.server.PlaceRegistry;

import com.threerings.parlor.server.ParlorManager;

import com.threerings.toybox.server.persist.ToyBoxRepository;

import static com.threerings.toybox.Log.log;

/**
 * The main entry point and general organizer of everything that goes on
 * in the ToyBox game server process.
 */
public class ToyBoxServer extends CrowdServer
{
    /** Configures dependencies needed by the ToyBox services. */
    public static class Module extends CrowdServer.Module
    {
        @Override protected void configure () {
            super.configure();
            bind(PlaceRegistry.class).to(ToyBoxPlaceRegistry.class);
            bind(Authenticator.class).to(ToyBoxConfig.getAuthenticator());
        }
    }

    /** The connection provider used to obtain access to our JDBC
     * databases. */
    public static ConnectionProvider conprov;

    /** The parlor manager in operation on this server. */
    public static ParlorManager parmgr = new ParlorManager();

    /** Handles ToyBox-specific functionality. */
    public static ToyBoxManager toymgr = new ToyBoxManager();

    @Override // from CrowdServer
    public void init (Injector injector)
        throws Exception
    {
        super.init(injector);

        // configure the client manager to use the appropriate client class
        clmgr.setClientFactory(new ClientFactory() {
            public PresentsClient createClient (AuthRequest areq) {
                return new ToyBoxClient();
            }
            public ClientResolver createClientResolver (Name username) {
                return new ToyBoxClientResolver();
            }
        });

        // create our database connection provider
        conprov = new StaticConnectionProvider(ToyBoxConfig.getJDBCConfig());

        // initialize our managers
        parmgr.init(invmgr, plreg);

        // determine whether we've been run in test mode with a single game configuration
        String gconfig = System.getProperty("game_conf");
        ToyBoxRepository toyrepo = null;
        if (StringUtil.isBlank(gconfig)) {
            toyrepo = new ToyBoxRepository(conprov);
        }
        toymgr.init(omgr, invoker, invmgr, plreg, toyrepo);
        if (!StringUtil.isBlank(gconfig)) {
            toymgr.setDevelopmentMode(new File(gconfig));
        }

        log.info("ToyBox server initialized.");
    }

    /**
     * Returns the port on which the connection manager will listen for client connections.
     */
    protected int[] getListenPorts ()
    {
        return new int[] { ToyBoxConfig.getServerPort() };
    }

    protected static class ToyBoxPlaceRegistry extends PlaceRegistry {
        @Inject public ToyBoxPlaceRegistry (
            ShutdownManager shutmgr, InvocationManager invmgr, RootDObjectManager omgr) {
            super(shutmgr, invmgr, omgr);
        }
        @Override public ClassLoader getClassLoader (PlaceConfig config) {
            ClassLoader loader = toymgr.getClassLoader(config);
            return (loader == null) ? super.getClassLoader(config) : loader;
        }
    }

    public static void main (String[] args)
    {
        Injector injector = Guice.createInjector(new Module());
        ToyBoxServer server = injector.getInstance(ToyBoxServer.class);
        try {
            server.init(injector);
            server.run();
        } catch (Exception e) {
            log.warning("Unable to initialize server.", e);
        }
    }
}

@@ -1894,24 +1894,73 @@
 rowdServer;%0A
+import com.threerings.crowd.server.PlaceManager;%0A
 import com.t
@@ -4665,29 +4665,16 @@
 gistry (
-%0A            
 Shutdown
@@ -4692,59 +4692,8 @@
 tmgr
-, InvocationManager invmgr, RootDObjectManager omgr
 ) %7B%0A
@@ -4721,22 +4721,8 @@
 tmgr
-, invmgr, omgr
 );%0A 
@@ -4753,38 +4753,46 @@
 de p
-ublic ClassLoader getClassLoad
+rotected PlaceManager createPlaceManag
 er (
@@ -4810,16 +4810,33 @@
  config)
+ throws Exception
  %7B%0A     
@@ -4906,22 +4906,18 @@
         
-return
+if
  (loader
@@ -4930,47 +4930,202 @@
 ll) 
-? super.getClassLoader(config) : loader
+%7B%0A                return super.createPlaceManager(config);%0A            %7D%0A            return (PlaceManager)Class.forName(%0A                config.getManagerClassName(), true, loader).newInstance()
 ;%0A  

Create our sandboxed place managers using the new calldown method.