Package net.yura.lobby.server

Source Code of net.yura.lobby.server.LobbyServer

package net.yura.lobby.server;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
import net.yura.grasshopper.BugManager;
import net.yura.grasshopper.ReallySimpleFormatter;
import net.yura.lobby.client.ProtoAccess;
import net.yura.lobby.client.ProtoAccess.ObjectProvider;
import net.yura.lobby.database.GameRoom;
import net.yura.lobby.database.User;
import net.yura.lobby.gen.ProtoLobby;
import net.yura.lobby.model.Game;
import net.yura.lobby.model.GameType;
import net.yura.lobby.model.Message;
import net.yura.lobby.model.Player;

/**
* @author Yura Mamyrin
*/
public class LobbyServer implements ObjectProvider {
   
    public static final Logger logger = Logger.getLogger(LobbyServer.class.getName());
   
    private static final int PROTOCOL_VERSION = 1;

    public static String[] args;
    public static final String NEW_HOST_ARG = "--newHost=";

    final ProtoAccess access = new ProtoAccess(this);
    public final GameLobby lobby;

    public LobbyServer(SocketServer sserver) {
        lobby = new GameLobby(sserver);

        for (String arg:args) {
            if (arg.startsWith(NEW_HOST_ARG)) {
                lobby.setNewHost( arg.substring( NEW_HOST_ARG.length() ) );
            }
        }
    }
   
    public void handleMessage(LobbySession session, Message msg) {

        String command = msg.getCommand();
        Object param = msg.getParam();

        if (msg.getWait()!=null) {
            try {
                Thread.sleep( msg.getWait() );
            }
            catch (InterruptedException in) {
                Thread.currentThread().interrupt();
            }
        }

        logger.info("Got "+session+" "+msg);

        try {

            if (ProtoAccess.REQUEST_HELLO.equals(command)) {
                Map request = (Map)param;

                Integer version = (Integer)request.get("version");

                String appName = (String)request.get("appName");
                String appVersion = (String)request.get("appVersion");
               
                session.setClientVersion(appName+" "+appVersion);
               
                if (version.intValue() == PROTOCOL_VERSION) {
                    String uuid = (String)request.get("uuid");
                    lobby.connected( session, uuid, getEncodedPublicKey() );
                }
                else {
                    throw new RuntimeException("version miss match, server="+PROTOCOL_VERSION+" client="+version);
                }
            }
            else if (ProtoAccess.REQUEST_LOGIN.equals(command)) {
                throw new UnsupportedOperationException("Not supported yet.");
            }
            else if (ProtoAccess.REQUEST_REGISTER.equals(command)) {
                throw new UnsupportedOperationException("Not supported yet.");
            }
            else if (ProtoAccess.REQUEST_LOGOUT.equals(command)) {
                throw new UnsupportedOperationException("Not supported yet.");
            }
            else if (ProtoAccess.REQUEST_SET_NICK.equals(command)) {
                Map request = (Map)param;
                Object uobj = request.get("username");
                String username = uobj instanceof String?(String)uobj:decrypt( (byte[])uobj );
                lobby.setNick(session, username);
            }
            else if (ProtoAccess.REQUEST_ALL_GAMETYPES.equals(command)) {
                lobby.sendGameTypes(session);
            }
            else if (ProtoAccess.REQUEST_GET_GAMES.equals(command)) {
                Map map = (Map)param;
                lobby.setCurrentGameType(session, (Integer)map.get("game_type_id") );
            }
            else if (ProtoLobby.REQUEST_CREATE_NEW_GAME.equals(command)) {
                Game game = (Game)param;

                if (game.getId() >= 0) {
                    assertAmMod(session); // only admin can edit existing games.
                    try {
                        lobby.database.startTransaction();
                        GameRoom gameRoom = lobby.database.getGame(game.getId());
                        if (!gameRoom.getName().equals(game.getName())) {
                            gameRoom.setName( game.getName() );
                            lobby.database.saveGame(gameRoom);
                            lobby.gameChanged(gameRoom);
                        }
                        // TODO we may want to resign/add players
                    }
                    finally {
                        lobby.database.endTransaction();
                    }
                }
                else {
                    if (game.getPlayers().isEmpty()) {
                        GameRoom gameRoom = lobby.createGame(game);
                        lobby.joinGame(session.getUsername(), gameRoom.getId());
                    }
                    else {
                        Set<Player> players = game.getPlayers();
                        game.setPlayers(new HashSet());
                        GameRoom gameRoom = lobby.createGame(game);
                        // TODO somehow need to tell the DB this is a private game
                        for (Player player: players) {
                            gameRoom = lobby.joinGame(player.getName(), gameRoom.getId(), session);
                        }
                        // tell everyone about the game.
                        lobby.gameChanged(gameRoom);
                    }
                }
            }
            else if (ProtoLobby.REQUEST_DEL_GAME.equals(command)) {
                assertAmMod(session);
                Map map = (Map)param;
                lobby.removeGame((Integer) map.get("game_id"));
            }
            else if (ProtoLobby.REQUEST_RESIGN_FROM_ALL_GAMES.equals(command)) {
                assertAmMod(session);
                Map map = (Map)param;
                lobby.resignFromAllGames((String) map.get("username"));
            }
            else if (ProtoLobby.REQUEST_RENAME_USER.equals(command)) {
                assertAmMod(session);
                Map map = (Map)param;
                lobby.setNick((String) map.get("oldName"), (String) map.get("newName"));
            }
            else if (ProtoLobby.REQUEST_JOIN_GAME.equals(command)) {
                Map map = (Map)param;
                lobby.joinGame(session.getUsername(), (Integer)map.get("game_id") );
            }
            else if (ProtoLobby.REQUEST_LEAVE_GAME.equals(command)) {
                Map map = (Map)param;
                lobby.leaveGame(session.getUsername(), (Integer)map.get("game_id") );
            }
            else if (ProtoLobby.REQUEST_PLAY_GAME.equals(command)) {
                Map map = (Map)param;
                lobby.playOrWatch(session, (Integer)map.get("game_id") );
            }
            else if (ProtoLobby.REQUEST_CLOSE_GAME.equals(command)) {
                Map map = (Map)param;
                lobby.stopPlayOrWatch(session, (Integer)map.get("game_id") );
            }
            else if (ProtoLobby.REQUEST_GAME_MESSAGE.equals(command)) {
                Map map = (Map)param;
                lobby.messageForGame( (Integer)map.get("game_id"), session.getUsername(), map.get("message") );
            }
            else if (ProtoLobby.COMMAND_CHAT_MESSAGE.equals(command)) {
                Map map = (Map)param;
                lobby.sendChatMessage( (Integer)map.get("room_id"), session.getUsername(), (String)map.get("message") );
            }
            else if (ProtoLobby.REQUEST_ANDROID_REGISTER.equals(command)) {
                lobby.registerGCM(session,(String)param);
            }
            else if (ProtoLobby.REQUEST_ANDROID_UNREGISTER.equals(command)) {
                lobby.unregisterGCM(session, (String)param );
            }
            else {
                throw new IllegalArgumentException("unknown command "+command);
            }

        }
        catch (Exception ex) {
            lobby.send( session,ProtoAccess.COMMAND_SERVER_ERROR, ex.toString() );
            logger.log(Level.WARNING, "error dealing with "+session+" "+command+" "+param, ex);
        }
    }

    public void gotConnected(LobbySession ch) {
    }
    public void lostConnection(LobbySession ch) {
        lobby.disconnected(ch);
    }
    public void closingConnection(LobbySession ch) {
        lobby.disconnected(ch);
    }




    public Message decode(InputStream in,int size) throws IOException {
        return (Message)access.load(in, size);
    }

    public void encode(OutputStream out, Message message) throws IOException {
        int size = access.computeAnonymousObjectSize(message);
        DataOutputStream dout = new DataOutputStream(out);
        dout.writeInt(size);
        access.save(out, message);
    }

    @Override
    public Object getObjectId(Object object) {
        if (object instanceof GameType) {
            return new Integer( ((GameType)object).getId() );
        }
        throw new IllegalArgumentException("what is this object? "+object );
    }

    @Override
    public Object getObjetById(Object id, Class clas) {
        if (clas == GameType.class) {
            return lobby.getGameType( ((Integer)id).intValue() );
        }
        throw new IllegalArgumentException("what is this class? "+clas+" "+id);
    }





    private static KeyPairGenerator kpg;
    private static RSAPrivateKey privKey;
    private static RSAPublicKey pubKey;
    private static byte[] encodedPubKey;
    private static Cipher decrypt;
    private static final String cipher = "RSA";
    static {
        try {
            kpg = KeyPairGenerator.getInstance(cipher);
            decrypt = Cipher.getInstance(cipher);
            kpg.initialize(1024);
            generateNewKeys();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
    static byte[] getEncodedPublicKey() {
        return encodedPubKey;
    }

    static synchronized String decrypt(byte[] message) {
        try {
            return new String( decrypt.doFinal(message) ,"UTF-8");
        }
        catch (Exception e) {
            throw new RuntimeException("failed to decrypt",e);
        }
    }
    private static void generateNewKeys() {

        KeyPair kp = kpg.generateKeyPair();
        privKey = (RSAPrivateKey)kp.getPrivate();
        pubKey = (RSAPublicKey)kp.getPublic();
        //LobbyServer.log(pubKey.toString(),Level.INFO);
        encodedPubKey = pubKey.getEncoded();
        try {
            decrypt.init(Cipher.DECRYPT_MODE,privKey);
        } catch(Exception e) {
            e.printStackTrace();
        }

    }

    public static boolean equals(Object a, Object b) {
        return (a == b) || (a != null && a.equals(b));
    }
   
   
   
    public static void setupLogging() throws IOException {

        // intercept System.out.and System.err to java.util.logging
        BugManager.intercept();

        //setup logger to log to file
        File log = new File("./log/");
        if(!log.canRead())  {
            if (!log.mkdir()) {
                throw new IllegalStateException("can not mkdir "+log);
            }
        }
        else {
            File old = new File(log,"old");
            if(!old.canRead())  {
                if (!old.mkdir()) {
                    throw new IllegalStateException("can not mkdir "+old);
                }
            }
            else {
                // del all old log files
                for(File file: old.listFiles()) {
                    if (file.isFile()) {
                        file.delete();
                    }
                }
            }
            for(File file: log.listFiles()) {
                if (file.isFile()) {
                    File oldFile = new File(old,file.getName());
                    if (!file.renameTo(oldFile)) {
                        throw new IllegalStateException("can not rename "+file+" to "+oldFile);
                    }
                }
            }
        }

        Logger logger = Logger.getLogger("");
        int fileSize = 1024*1024*100; // 100 MB
        FileHandler txtLog = new FileHandler("log/LobbyServer.%g.log",fileSize,100,true);
        //txtLog.setFormatter(new org.quickserver.util.logging.MicroFormatter());
        txtLog.setFormatter( new ReallySimpleFormatter() );
        logger.addHandler(txtLog);

        // log SQL
        //Logger.getLogger("DataNucleus.Datastore.Native").setLevel(Level.FINEST);
       
    }

    private void assertAmMod(LobbySession session) {
        try {
            lobby.database.startTransaction();
            User me = lobby.database.getUser(session.getUsername());
            if (me.getType() < Player.PLAYER_MODERATOR) {
                throw new SecurityException("what do you think you are doing!");
            }
        }
        finally {
            lobby.database.endTransaction();
        }
    }
   
   
}
TOP

Related Classes of net.yura.lobby.server.LobbyServer

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.