vn.com.vng.gsmobile.casino.client.ClientHandler.java Source code

Java tutorial

Introduction

Here is the source code for vn.com.vng.gsmobile.casino.client.ClientHandler.java

Source

/*
 * Copyright 2012 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
//The MIT License
//
//Copyright (c) 2009 Carl Bystrm
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.

package vn.com.vng.gsmobile.casino.client;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Map;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.io.IOUtils;
import com.google.flatbuffers.FlatBufferBuilder;
import com.google.flatbuffers.Table;
import io.netty.buffer.ByteBufInputStream;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
import io.netty.handler.codec.http.websocketx.PongWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.util.CharsetUtil;
import vn.com.vng.gsmobile.casino.entries.Bot;
import vn.com.vng.gsmobile.casino.entries.CMD;
import vn.com.vng.gsmobile.casino.flatbuffers.CMDGame3LaShowCard;
import vn.com.vng.gsmobile.casino.flatbuffers.CMDGameTLMNSkip;
import vn.com.vng.gsmobile.casino.flatbuffers.CMDGameTLMNUpdate;
import vn.com.vng.gsmobile.casino.flatbuffers.CMDInviteGame;
import vn.com.vng.gsmobile.casino.flatbuffers.CMDJoinGame;
import vn.com.vng.gsmobile.casino.flatbuffers.CMDQuitGame;
import vn.com.vng.gsmobile.casino.flatbuffers.Game3LaGameInfo;
import vn.com.vng.gsmobile.casino.flatbuffers.GameRoomState;
import vn.com.vng.gsmobile.casino.flatbuffers.GameTLMNInfo;
import vn.com.vng.gsmobile.casino.flatbuffers.JoinGameType;
import vn.com.vng.gsmobile.casino.flatbuffers.QuitState;
import vn.com.vng.gsmobile.casino.flatbuffers.RoomResponse;
import vn.com.vng.gsmobile.casino.ulti.GZip;
import vn.com.vng.gsmobile.casino.ulti.Lib;

public class ClientHandler extends SimpleChannelInboundHandler<Object> {
    private Long uid = 0l;
    private final WebSocketClientHandshaker handshaker;
    private ChannelPromise handshakeFuture;

    public ClientHandler(Long uid, WebSocketClientHandshaker handshaker) {
        this.uid = uid;
        this.handshaker = handshaker;
    }

    public ChannelFuture handshakeFuture() {
        return handshakeFuture;
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        handshakeFuture = ctx.newPromise();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        handshaker.handshake(ctx.channel());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        Lib.getLogger().debug(Arrays.asList(uid, ctx.channel().id(), "disconnected",
                this.getClass().getSimpleName() + ".channelInactive"));
        Bot b = Bot.list.get(uid);
        if (b != null)
            b.reconnect();
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        Channel ch = ctx.channel();
        if (!handshaker.isHandshakeComplete()) {
            handshaker.finishHandshake(ch, (FullHttpResponse) msg);
            Lib.getLogger().debug(Arrays.asList(uid, ctx.channel().id(), "connected",
                    this.getClass().getSimpleName() + ".channelRead0"));
            handshakeFuture.setSuccess();
            return;
        }

        if (msg instanceof FullHttpResponse) {
            FullHttpResponse response = (FullHttpResponse) msg;
            throw new IllegalStateException("Unexpected FullHttpResponse (getStatus=" + response.status()
                    + ", content=" + response.content().toString(CharsetUtil.UTF_8) + ')');
        }

        WebSocketFrame frame = (WebSocketFrame) msg;
        if (frame instanceof BinaryWebSocketFrame) {
            receiptFormServer(ctx, frame);
        } else if (frame instanceof PingWebSocketFrame) {
            ch.writeAndFlush(new PongWebSocketFrame());
            Lib.getLogger().trace(Arrays.asList(uid, ctx.channel().id(), "pong:OK",
                    this.getClass().getSimpleName() + ".channelRead0"));
        } else if (frame instanceof CloseWebSocketFrame) {
            Lib.getLogger().debug(Arrays.asList(uid, ctx.channel().id(), "received closing",
                    this.getClass().getSimpleName() + ".channelRead0"));
            ch.close();
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        Lib.getLogger().error(Arrays.asList(ctx.channel().id(), ctx, Lib.getStackTrace(cause),
                this.getClass().getSimpleName() + ".exceptionCaught"));
        if (!handshakeFuture.isDone()) {
            handshakeFuture.setFailure(cause);
        }
        ctx.close();
        Bot b = Bot.list.get(uid);
        if (b != null)
            b.reconnect();
    }

    @SuppressWarnings({ "rawtypes" })
    private void receiptFormServer(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception {
        ByteBufInputStream bbi = new ByteBufInputStream(frame.content());
        byte c1 = bbi.readByte();
        byte c2 = bbi.readByte();
        byte c3 = bbi.readByte();
        byte c4 = bbi.readByte();
        if (c4 == 0) {
            int gzip = ((int) c3 & (int) 0x80) >> 7;
            int version = (int) c3 & (int) 0x7F;
            String sCMD = c1 + "_" + c2 + "_" + version;
            Map mService = (Map) Lib.getServiceConfig(false).get(sCMD);
            if (mService != null) {
                //1. Gii nn
                byte[] b = null;
                if (gzip == 1)
                    b = GZip.decompress(IOUtils.toByteArray(bbi));
                else
                    b = IOUtils.toByteArray(bbi);
                //2. Gii m
                byte[] b1 = null;
                //            Object oSecKey = mService.get("server_seckey");
                //            if("1".equals(Const.SESSION_KEY) && "1".equals(oSecKey)){
                //               //Giai ma data request
                //               Session s = new Session(sUID);
                //               String sk = s.hget(Session.SECKEY);
                //               if(sk !=null){
                //                   b1 = XXTEA.decrypt(b, sk.getBytes());
                //               }
                //            }
                ByteBuffer bb = ByteBuffer.wrap(b1 == null ? b : b1);
                Object oData = null;
                Object oServer = mService.get("server");
                if (oServer != null) {
                    Class<?> clsRequest = Class.forName(mService.get("server").toString());
                    try {
                        oData = Lib.invoke(clsRequest, "getRootAs" + clsRequest.getSimpleName(),
                                new Class<?>[] { ByteBuffer.class }, new Object[] { bb });
                    } catch (Exception e) {
                        oData = new String(b, Charset.forName("UTF-8"));
                    }
                }
                Lib.getLogService().debug(Arrays.asList(uid, ctx.channel().id(), c1, c2, c3, c4, oData.toString(),
                        this.getClass().getSimpleName() + ".receiptFormServer"));
                Bot bot = Bot.list.get(uid);
                FlatBufferBuilder builder = new FlatBufferBuilder(0);
                Table data = null;
                Integer state = null;
                Integer turnIdx = null;
                Integer playIdx = null;
                Long battleId = null;
                Long roomId = null;
                CMD cmd = CMD.getCMD(c1, c2, (byte) version);
                switch (cmd) {
                case ROOM_WAIT:
                    RoomResponse rs = (RoomResponse) oData;
                    if (rs != null) {
                        builder.finish(CMDJoinGame.createCMDJoinGame(builder, uid, rs.room().id(),
                                JoinGameType.PLAY, builder.createString("trid"), 0));
                        data = CMDJoinGame.getRootAsCMDJoinGame(builder.dataBuffer());
                        bot.write(CMD.JOIN_ROOM, data);
                    }
                    break;
                case INVITE_ROOM:
                    CMDInviteGame iv = (CMDInviteGame) oData;
                    builder.finish(CMDJoinGame.createCMDJoinGame(builder, uid, iv.roomId(), JoinGameType.PLAY,
                            builder.createString("trid"), 0));
                    data = CMDJoinGame.getRootAsCMDJoinGame(builder.dataBuffer());
                    bot.write(CMD.JOIN_ROOM, data);
                    break;
                case JOIN_ROOM:
                    RoomResponse rs2 = (RoomResponse) oData;
                    if (rs2 != null) {
                        bot.setRoomId(rs2.room().id());
                    }
                    break;
                case QUIT_ROOM:
                    CMDQuitGame qg = (CMDQuitGame) oData;
                    if (qg.state() == QuitState.QUIT_ACCEPT || qg.state() == QuitState.QUIT_NOT_ENOUGH_MONEY
                            || qg.state() == QuitState.QUIT_POOR_CONNECTION)
                        bot.setRoomId(null);
                    break;
                case TLMN_UPDATE_BATTLE_INFO:
                case TLMN_BATTLE_INFO:
                    GameTLMNInfo gif = (GameTLMNInfo) oData;
                    roomId = gif.roomId();
                    battleId = gif.gameId();
                    state = gif.state();
                    turnIdx = gif.turnIdx();
                    playIdx = gif.playerIdx();
                    if (state == GameRoomState.Finished) {
                        bot.setPlayerIdx(null);
                    } else if (state == GameRoomState.Playing) {
                        for (int j = 0; j < gif.cardListLength(); j++) {
                            if (gif.cardList(j).playerId() == bot.getId()) {
                                bot.setPlayerIdx(j);
                                break;
                            }
                        }
                    }

                    //skip turn here
                    if (bot.getPlayerIdx() == playIdx && state == GameRoomState.Playing) {
                        builder.finish(
                                CMDGameTLMNSkip.createCMDGameTLMNSkip(builder, roomId, battleId, turnIdx, playIdx));
                        data = CMDGameTLMNSkip.getRootAsCMDGameTLMNSkip(builder.dataBuffer());
                        bot.write(CMD.TLMN_SKIP_TURN, data);
                    }
                    break;
                case TLMN_UPDATE_BATTLE_INFO_TINY:
                    CMDGameTLMNUpdate gup = (CMDGameTLMNUpdate) oData;
                    roomId = gup.roomId();
                    battleId = gup.gameId();
                    state = gup.state();
                    turnIdx = gup.nextTurnIdx();
                    playIdx = gup.nextPlayerIdx();
                    synchronized (bot) {
                        bot.wait(2000);
                    }
                    //skip turn here
                    if (bot.getPlayerIdx() == playIdx && state == GameRoomState.Playing) {
                        builder.finish(
                                CMDGameTLMNSkip.createCMDGameTLMNSkip(builder, roomId, battleId, turnIdx, playIdx));
                        data = CMDGameTLMNSkip.getRootAsCMDGameTLMNSkip(builder.dataBuffer());
                        bot.write(CMD.TLMN_SKIP_TURN, data);
                    }
                    break;
                case CAO_BATTLE_INFO:
                    Game3LaGameInfo gif3 = (Game3LaGameInfo) oData;
                    roomId = gif3.roomId();
                    battleId = gif3.gameId();
                    state = gif3.state();
                    if (state == GameRoomState.Finished) {
                        bot.setPlayerIdx(null);
                    } else if (state == GameRoomState.Playing) {
                        for (int j = 0; j < gif3.cardListLength(); j++) {
                            if (gif3.cardList(j).playerId() == bot.getId()) {
                                bot.setPlayerIdx(j);
                                break;
                            }
                        }
                    }
                    if (state == GameRoomState.Playing) {
                        synchronized (bot) {
                            bot.wait(2000);
                        }
                        builder.finish(CMDGame3LaShowCard.createCMDGame3LaShowCard(builder, roomId, battleId,
                                bot.getPlayerIdx(),
                                CMDGame3LaShowCard.createShowedCardsVector(builder, new byte[] { 0, 1, 2 })));
                        data = CMDGameTLMNSkip.getRootAsCMDGameTLMNSkip(builder.dataBuffer());
                        bot.write(CMD.CAO_SHOW_CARDS, data);
                    }
                    break;
                default:
                    break;
                }
            } else {
                Lib.getLogService()
                        .debug(Arrays.asList(uid, ctx.channel().id(), c1, c2, c3, c4,
                                Hex.encodeHexString(IOUtils.toString(bbi).getBytes()),
                                this.getClass().getSimpleName() + ".receiptFormServer"));
            }
        } else
            Lib.getLogService().debug(Arrays.asList(uid, ctx.channel().id(), c1, c2, c3, c4,
                    Lib.getErrorMessage(c4), this.getClass().getSimpleName() + ".receiptFormServer"));
    }
}