Package gwlpr.mapshard.controllers

Source Code of gwlpr.mapshard.controllers.ClientConnect

/**
* For copyright information see the LICENSE document.
*/

package gwlpr.mapshard.controllers;

import gwlpr.mapshard.models.ClientBean;
import gwlpr.mapshard.models.WorldBean;
import gwlpr.mapshard.models.enums.PlayerState;
import gwlpr.protocol.handshake.HandShakeDoneEvent;
import gwlpr.protocol.handshake.messages.P000_VerifyClient.Payload;
import gwlpr.protocol.intershard.GSNotify_ClientConnected;
import gwlpr.protocol.intershard.GSReply_AcceptClient;
import gwlpr.protocol.intershard.LSRequest_AcceptClient;
import io.netty.channel.Channel;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import realityshard.container.events.Event;
import realityshard.container.gameapp.GameAppContext;
import realityshard.container.network.GameAppContextKey;
import realityshard.container.util.Handle;
import realityshard.container.util.HandleRegistry;


/**
* This handles all incoming client connections.
* We will get instructed by the parent login shard to actually accept certain
* clients. (To link them with this mapshard)
*
* @author _rusty
*/
public class ClientConnect
{

    private static Logger LOGGER = LoggerFactory.getLogger(ClientConnect.class);

    private final java.util.Map<UUID, ClientBean> uninitializedClients = new ConcurrentHashMap<>();

    private final Handle<GameAppContext> context;
    private final Handle<GameAppContext> loginShard;
    private final HandleRegistry<ClientBean> clientRegistry;

    private final WorldBean world;


    /**
     * Constructor.
     *
     * @param       context                 This context
     * @param       loginShard              The parent context, i.e. the login shard.
     * @param       clientRegistry
     * @param       world
     */
    public ClientConnect(
            Handle<GameAppContext> context,
            Handle<GameAppContext> loginShard,
            HandleRegistry<ClientBean> clientRegistry,
            WorldBean world)
    {
        this.context = context;
        this.loginShard = loginShard;
        this.clientRegistry = clientRegistry;

        this.world = world;
    }


    /**
     * Intershard communication event handler.
     *
     * TODO: check if we already got too much clients and such...
     *
     * @param event
     */
    @Event.Handler
    public void onAcceptClientRequest(LSRequest_AcceptClient event)
    {
        // create a new uninitialized client bean...
        ClientBean client = new ClientBean(event.getAccount(), event.getCharacter());

        // and add it to our controller internal mapping...
        uninitializedClients.put(event.getClientUid(), client);

        // and tell the LS that we're ready
        loginShard.get().trigger(
                new GSReply_AcceptClient(
                    context.getUid(),
                    event.getClientUid(),
                    true));
    }


    /**
     * Event handler.
     *
     * @param       event
     */
    @Event.Handler
    public void onHandshakeDone(HandShakeDoneEvent event)
    {
        LOGGER.debug("Got a new client to verify.");

        Payload verifyClient = event.getVerifyClient();

        // failcheck
        if (verifyClient == null) { return; }

        // check the server key
        if (((int)verifyClient.Key1) != context.getUid().hashCode()) { return; }

        // check if we got the client key
        UUID clientUid = null;
        for (UUID uuid : uninitializedClients.keySet())
        {
            if (((int)verifyClient.Key2) == uuid.hashCode())
            {
                // found the client!
                clientUid = uuid;
                break;
            }
        }

        // failcheck
        if (clientUid == null) { return; }

        LOGGER.debug("Client accepted.");

        // initialize the client bean first
        ClientBean client = uninitializedClients.remove(clientUid);
        client.init(event.getChannel());

        PlayerState state = world.isCharCreate() ? PlayerState.CreatingCharacter : PlayerState.LoadingInstance;
        client.setPlayerState(state);

        // sign the client
        Channel channel = client.getChannel();
        channel.attr(GameAppContextKey.KEY).set(context.get());
        channel.attr(GameAppContextKey.IS_SET).set(true);

        // register it
        // this will trigger an event from the client registry notification decorator,
        // instructing other controllers to deal with this newly registered client
        Handle<ClientBean> clientHandle = clientRegistry.registerExisting(client, clientUid);
        channel.attr(ClientBean.HANDLE_KEY).set(clientHandle);

        // also inform the login shard
        loginShard.get().trigger(
                new GSNotify_ClientConnected(
                    context.getUid(),
                    clientUid));

        LOGGER.debug("Client connected to the mapshard successfully.");
    }
}
TOP

Related Classes of gwlpr.mapshard.controllers.ClientConnect

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.