package com.game; import java.util.List; import java.util.Map; import com.data.bean.AccountBean; import com.data.cache.AccountCache; import com.data.cache.BaseCache; import com.data.cache.GroupMemberCache; import com.data.util.ErrorCode; import com.data.util.EventType; import com.data.util.Utility; import com.game.data.JoinRoomData; import com.game.data.Player; import com.game.data.Room; import com.game.player.state.PlayerInitState; import com.game.player.state.PlayerReadyState; import com.game.room.state.RoomDestoryGameState; import com.taurus.core.entity.ITArray; import com.taurus.core.entity.ITObject; import com.taurus.core.entity.TArray; import com.taurus.core.entity.TObject; import com.taurus.core.plugin.redis.Redis; import com.taurus.core.plugin.redis.RedisLock; import com.taurus.core.routes.ActionKey; import com.taurus.core.routes.IController; import com.taurus.core.util.StringUtil; import com.taurus.permanent.data.Session; import redis.clients.jedis.Jedis; /** * 基本游戏控制器 * */ public class GameController implements IController { /** * 聊天 */ @ActionKey(Router.GAME_INTERACTION) public void routerChat(Session sender, ITObject params, int gid, Player owner) { owner.room.broadCastToClient(0, Router.GAME_EVT_INTERACTION, params); } /** * 请求准备 * */ @ActionKey(Router.GAME_READY) public void routerReady(Session sender, ITObject params, int gid, Player owner) { owner.stateMachine.execute(ActionEvent.EVENT_READY, gid, params); } /** * 请求准备 * */ @ActionKey(Router.GAME_READY_AND_XIPAI) public void routerReadyAndXiPai(Session sender, ITObject params, int gid, Player owner) { owner.stateMachine.execute(ActionEvent.EVENT_READY_AND_XIPAI, gid, params); } /** * 请求开始游戏 */ @ActionKey(Router.GAME_START) public void routerStartGame(Session sender, ITObject params, int gid, Player owner) { owner.room.stateMachine.execute(ActionEvent.EVENT_START_GAME, gid, params); } @ActionKey(Router.GAME_XIPAI) public void RouterXiPai(Session sender, ITObject params, int gid, Player owner) { owner.stateMachine.execute(ActionEvent.EVENT_XIPAI, 0, params); owner.room.stateMachine.execute(ActionEvent.EVENT_XIPAI, 0, params); } /** * 托管 * */ @ActionKey(Router.GAME_ENTRUST) @SuppressWarnings("unchecked") public void routerEntrust(Session sender, ITObject params, int gid, Player owner) { if (owner.room.status == Constant.ROOM_STATUS_PLAYING && owner.room.isEntrust()) { owner.entrust = params.getBoolean("ok"); Global.gameCtr.updatePlayerEntrust(owner); Global.logger.info(owner + " manual " + (owner.entrust ? "entrust" : "quitEntrust")); if (owner.entrust) { owner.setEntrustData(params); owner.stateMachine.curState.execute(owner, ActionEvent.EVENT_ENTRUST, gid, params); } else { owner.exitEntrust(); } } } /** * 请求进入房间 */ @ActionKey(value = Router.GAME_JOIN_ROOM, validate = GameInterceptor.NOT_PLAYER) public void routerJoinRoom(Session sender, ITObject params, int gid) { String session_id = params.getUtfString("session"); // String sessionToken = Utils.getUniqueSessionToken(sender); String token = null; if (StringUtil.isEmpty(session_id)) { Global.logger.info("---------------参数session为null,参数params:{}", params); session_id = ""; } else { String[] sourceStrArray = session_id.split(","); if (sourceStrArray.length == 2) { session_id = sourceStrArray[0]; token = sourceStrArray[1]; } if (StringUtil.isNotEmpty(token) && StringUtil.isNotEmpty(session_id)) { String token_session = Redis.use("group1_db0").hget(token, "user"); if (StringUtil.isEmpty(token_session)) { MainServer.instance.sendResponse(gid, ErrorCode._NO_SESSION, null, sender); return; } else { if (!token_session.equals(session_id)) { MainServer.instance.sendResponse(gid, ErrorCode._NO_SESSION, null, sender); return; } } } else { MainServer.instance.sendResponse(gid, ErrorCode._NO_SESSION, null, sender); return; } } sender.setHashId(session_id); String pos = params.getUtfString("pos"); Global.roomMgr.joinRoom(sender, session_id, gid, pos); } /** * 自动出牌 */ @ActionKey(Router.GAME_AUTO_CARD) public void routerAutoCard(Session sender, ITObject params, int gid, Player owner) { owner.manualAutoCard = params.getBoolean("autoCard"); if (owner.manualAutoCard) { if (!owner.room.openEntrust) { owner.manualAutoCard = false; return; } } owner.entrust = owner.manualAutoCard; Global.gameCtr.updatePlayerEntrust(owner); Global.logger.info(owner + " manualAutoCard " + (owner.entrust ? "entrust" : "quitEntrust")); if (owner.manualAutoCard) { owner.stateMachine.curState.execute(owner, ActionEvent.EVENT_ENTRUST, gid, params); } else { owner.exitEntrust(); } } /** * 请求删除解散房间(外部) * */ @ActionKey(value = Router.GAME_REMOVE_ROOM, validate = GameInterceptor.NOT_PLAYER) public void routerRemoveRoom(Session sender, ITObject params, int gid) { try { String roomid = params.getUtfString("room"); // Global.logger.info(" ower del room : " + roomid); // if (Global.roomMgr.removeRoom(roomid)) { Global.logger.info(roomid + " is destroy!"); MainServer.instance.sendResponse(gid, 0, null, sender); // } else { // MainServer.instance.sendResponse(gid, 1, null, sender); // } } catch (Exception e) { Global.logger.error(e); MainServer.instance.sendResponse(gid, 1, null, sender); } } /** * 请求退出房间 */ @ActionKey(Router.GAME_EXIT_ROOM) public void routerExitRoom(Session sender, ITObject params, int gid, Player owner) { owner.stateMachine.execute(ActionEvent.EVENT_EXIT_ROOM, gid, params); } /** * 请求解散房间 */ @ActionKey(Router.GAME_ASK_DISMISS_ROOM) public void routerAskDismiss(Session sender, ITObject params, int gid, Player owner) { owner.room.dismissRunable.askDismiss(owner, gid); } /** * 房间解散投票请求 */ @ActionKey(Router.GAME_DISMISS_ROOM_VOTE) public void routerDismissRoomVote(Session sender, ITObject params, int gid, Player owner) { boolean agree = params.getBoolean("result"); owner.room.dismissRunable.responseDismiss(owner, agree); } /** * 请求更新GPS位置 * */ @ActionKey(Router.GAME_UPDATE_POS) public void routerUpdatePos(Session sender, ITObject params, int gid, Player owner) { owner.gps_pos = params.getUtfString("pos"); updatePlayerPos(owner); } /** * 入座 */ @ActionKey(Router.GAME_JOIN_SEAT) public void routerJoinSeat(Session sender, ITObject params, int gid, Player owner) { Global.gameCtr.joinSeat(owner, gid); } /** * 进入房间 * * @param parm * @param gid * @return */ @SuppressWarnings("unchecked") public int joinRoom(JoinRoomData parm, int gid) { Room owner = parm.room; String session_key = parm.session_key; Session sender = parm.sender; String gps_pos = parm.gps_pos; AccountBean acc = AccountCache.getAccount(session_key); int playerid = acc.id; boolean full = owner.playerMapBySeat.size() >= owner.maxPlayers; Global.logger.info("owner.status:" + owner.status); boolean reload = owner.status == Constant.ROOM_STATUS_PLAYING; String ip = acc.ip; if (StringUtil.isEmpty(ip)) { ip = sender.getAddress(); } Player player = null; boolean new_player = false; if (owner.playerMapById.containsKey(playerid)) { player = owner.playerMapById.get(playerid); if (player.isReload) { player.isReload = false; player.stateMachine.changeState(Global.getState(PlayerInitState.class)); } player.setSender(sender); Global.gameCtr.playerNetState(player); Global.gameCtr.updatePlayerPos(player); } else { if (full) { sender.setHashId(null); delRoomSeat(session_key, owner.room_key); return ErrorCode.ROOM_CLOSE; } // 检测是否打开GPS 、IP检测 boolean openGps = owner.isOpenGPSCheck(), openIP = owner.isOpenIPCheck(); if (openGps || openIP) { int errResult = 0; if (openGps) { Global.warn("room:{},playid:{},gps:{}", owner.room_key, playerid, gps_pos); // 开了检测GPS 但是未获取到位置、或未打开 if (!GPSUtil.isOpenGPS(gps_pos)) { errResult = 55; } // 距离过近 if (errResult == 0 && owner.checkGps(gps_pos)) { errResult = 54; } } if (openIP) { // 相同IP if (errResult == 0 && owner.checkIp(ip)) { errResult = 53; } } if (errResult != 0) { delRoomSeat(session_key, owner.room_key); return errResult; } } boolean onseat = true; long cur_hp = 0; if (onseat && owner.hpData != null) { cur_hp = Util.readRedisHp(owner.groupId, playerid); if (!checkHplimitInRoom(owner, cur_hp)) { return ErrorCode.GROUP_LIMIT_NO_HP; } } player = MainServer.instance.newPlayer(playerid, owner, session_key); if (player.room.upper_limit_hp == 0 || player.room.upper_limit_hp > cur_hp) { player.room.upper_limit_hp = cur_hp; } // Playez firstPlayer = player.room.playerMapBySeat.get(player.seat); // for (Map.Entry entry : player.room.playerMapBySeat.entrySet()) { // Player other = entry.getValue(); // if (other.hp.upper_limit_hp > firstPlayer.hp.upper_limit_hp) { // other.hp.upper_limit_hp = cur_hp; // }else { // player.hp.upper_limit_hp = cur_hp; // } // Global.logger.info(other.playerid + "当局赢分上限:" + other.hp.upper_limit_hp); // } player.hp.cur_hp = cur_hp; // Global.logger.info("当局赢分上限:" + player.room.upper_limit_hp); owner.addPlayer(player, false, onseat); player.setSender(sender); player.stateMachine.changeState(Global.getState(PlayerInitState.class)); new_player = true; } player.nick = acc.nick; player.portrait = acc.portrait; player.sex = acc.sex; player.ip = ip; if (StringUtil.isNotEmpty(gps_pos)) player.gps_pos = gps_pos; ITObject data = new TObject(); if (reload) { data.putTObject("reloadInfo", owner.getReloadInfo(player)); } data.putBoolean("reload", reload); data.putInt("owner", owner.owner_id); data.putInt("agent", owner.agent ? 1 : 0); data.putInt("createTime", Integer.parseInt(owner.redis_room_map.get("create_time"))); data.putTObject("tableInfo", owner.getRoomInfo(player)); player.response(data, gid, 0); if (new_player && player.seat != 0) { owner.broadCastToClient(player.playerid, Router.GAME_EVT_PLAYER_JOIN, player.getInfo()); } Global.logger.info("reload:" + reload); player.stateMachine.curState.reload(player); if (reload) { owner.join_player = player; owner.dismissRunable.reload(player); owner.stateMachine.curState.reload(owner); owner.join_player = null; } return 0; } /** * 玩家不能进入房间,删除redis 玩家身上room、seat * * @param session_key * @param owner */ public void delRoomSeat(String session_key, String room_key) { Jedis jedis0 = Redis.use("group1_db0").getJedis(); RedisLock lock = new RedisLock(session_key, jedis0); try { lock.lock(); String cur_room = jedis0.hget(session_key, "room"); if (StringUtil.isNotEmpty(cur_room)) { if (cur_room.equals(room_key)) { jedis0.hdel(session_key, "room", "seat"); } } } finally { lock.unlock(); } } /** * 检测加人房间限制 * * @param owner * @return */ public boolean checkHplimitInRoom(Room room, long cur_hp) { if (room.hpData != null) { int limitInRoom = room.hpData.getInt("limitInRoom"); if (cur_hp < (long) limitInRoom) { return false; } } return true; } /** * 检测加人房间限制 * * @param owner * @return */ public boolean checkHplimitPlay(Room room, int cur_hp) { if (room.hpData != null) { int limitInRoom = room.hpData.getInt("limitInRoom"); if (cur_hp < limitInRoom) { return false; } } return true; } /** * 坐下 * * @param owner * @param gid */ public void joinSeat(Player owner, int gid) { } /** * 聊天转发 * * @param owner * @param params */ public void chat(Player owner, ITObject params) { owner.room.broadCastToClient(0, Router.GAME_EVT_INTERACTION, params); } /** * 托管事件 * * @param owner */ public void entrust(Player owner, int time) { ITObject broadParam = new TObject(); broadParam.putInt("aid", owner.playerid); broadParam.putInt("time", time); owner.room.broadCastToClient(0, Router.GAME_EVT_READY_ENTRUST, broadParam); Global.info("{} Ready Entrust, left time:{}", owner.playerid, time); } /** * 取消托管事件 * * @param owner */ public void cancelEntrust(Player owner) { ITObject broadParam = new TObject(); broadParam.putInt("aid", owner.playerid); owner.room.broadCastToClient(0, Router.GAME_EVT_CANCEL_READY_ENTRUST, broadParam); // Global.info("{} Cancel Ready Entrust", owner.playerid); } /** * 准备事件 * * @param owner */ public void ready(Player owner) { ITObject broadParam = new TObject(); broadParam.putInt("aid", owner.playerid); long cur_hp = Util.readRedisHp(owner.room.groupId, owner.playerid); if (cur_hp < owner.hp.cur_hp) { Global.logger.error("cur hp:" + cur_hp + " < hp.cur_hp:" + owner.hp.cur_hp + " playerId:" + owner.playerid); if (owner.room.round == 0 && (!checkHplimitInRoom(owner.room, cur_hp) || cur_hp == 0)) { owner.room.saveMilitaryTotal(true); owner.room.stateMachine.changeState(Global.getState(RoomDestoryGameState.class)); String gm_key = GroupMemberCache.genKey(owner.room.groupId, owner.playerid); Redis.use("group1_db10").hset(gm_key, "ban", "1"); Redis.use("group1_db10").hset(gm_key, "group_ban", "1"); return; } } owner.hp.cur_hp = cur_hp; boolean flag = true; if (owner.room.maxPlayers == owner.room.playerMapById.size()) { for (Map.Entry entry : owner.room.playerMapById.entrySet()) { if (entry.getValue().playerid != owner.playerid && !(entry.getValue().stateMachine.curState instanceof PlayerReadyState)) { flag = false; break; } } } else { flag = false; } if (flag) { broadParam.putInt("start", 1); } else { broadParam.putInt("start", 0); } owner.room.broadCastToClient(0, Router.GAME_EVT_READY, broadParam); owner.stateMachine.changeState(Global.getState(PlayerReadyState.class)); } /** * 准备和洗牌事件 * * @param owner */ public void readyAndXipai(Player owner) { if (owner.xi_pai == false) { owner.xi_pai = true; // owner.room.redisUpdateXiPaiPlayer(owner); } long cur_hp = Util.readRedisHp(owner.room.groupId, owner.playerid); if (cur_hp < owner.hp.cur_hp || cur_hp == 0) { Global.logger.error( "cur hp:" + cur_hp + " < >>>>> hp.cur_hp:" + owner.hp.cur_hp + " playerId:" + owner.playerid); if (owner.room.round == 0 && (!checkHplimitInRoom(owner.room, cur_hp) || cur_hp == 0)) { owner.room.saveMilitaryTotal(true); owner.room.stateMachine.changeState(Global.getState(RoomDestoryGameState.class)); String gm_key = GroupMemberCache.genKey(owner.room.groupId, owner.playerid); Redis.use("group1_db10").hset(gm_key, "ban", "1"); Redis.use("group1_db10").hset(gm_key, "group_ban", "1"); return; } } owner.hp.cur_hp = cur_hp; ITObject broadParam = new TObject(); broadParam.putInt("aid", owner.playerid); boolean flag = true; if (owner.room.maxPlayers == owner.room.playerMapById.size()) { for (Map.Entry entry : owner.room.playerMapById.entrySet()) { if (entry.getValue().playerid != owner.playerid && !(entry.getValue().stateMachine.curState instanceof PlayerReadyState)) { flag = false; break; } } } else { flag = false; } if (flag) { broadParam.putInt("start", 1); } else { broadParam.putInt("start", 0); } owner.room.broadCastToClient(0, Router.GAME_EVT_READY_AND_XIPAI, broadParam); owner.stateMachine.changeState(Global.getState(PlayerReadyState.class)); } /** * 解散房间通知 * * @param askPlayer * @param sender * @param time */ public void dismissRoom(Player askPlayer, Player sender, List playerList, int time) { ITObject parm = TObject.newInstance(); parm.putInt("req_aid", askPlayer.playerid); parm.putInt("time", time); ITArray list = TArray.newInstance(); parm.putTArray("list", list); for (Player player : playerList) { ITObject tem = TObject.newInstance(); tem.putInt("aid", player.playerid); tem.putInt("result", player.dismissState); list.addTObject(tem); } if (sender != null) { sender.sendEvent(Router.GAME_EVT_DISMISS_ROOM, parm); } else { askPlayer.room.broadCastToClient(0, Router.GAME_EVT_DISMISS_ROOM, parm); } } /** * 观众席 * * @param owner */ public void joinSpectator(Player owner) { if (owner.room.exitSeat(owner)) { if (Global.loggerDebug) { Global.logger.info(owner + " exit seat!"); } owner.seat = 0; ITObject data = new TObject(); data.putInt("aid", owner.playerid); owner.room.broadCastToClient(0, Router.GAME_EVT_JOIN_SPECTATOR, data); owner.room.stateMachine.execute(ActionEvent.EVENT_READY, 0, null); } } /** * 解散失败 * * @param owner */ public void dismisRoomFail(Room owner) { owner.broadCastToClient(0, Router.GAME_EVT_DISMISS_ROOM_FAIL, null); } /** * 退出房间 * * @param owner * @param gid */ public void exitRoom(Player owner, int gid, boolean kick) { if (kick) { owner.sendEvent(Router.GAME_EVT_KICK_PLAYER, null); } else { owner.response(null, gid, 0); } if (owner.room.status == Constant.ROOM_STATUS_NOBEGIN || owner.spectator) { int owner_id = owner.room.owner_id; if (!owner.room.agent && owner.playerid == owner_id) { owner.room.stateMachine.changeState(Global.getState(RoomDestoryGameState.class)); } else { // 在座位上 if (owner.room.playerMapBySeat.containsKey(owner.seat) && owner.room.playerMapBySeat.size() == 1) { ITObject data = new TObject(); data.putInt("aid", owner.playerid); owner.room.broadCastToClient(owner.playerid, Router.GAME_EVT_PLAYER_EXIT, data); int groupId = owner.room.groupId; String roomid = owner.room.roomid; try { delRoom(groupId, roomid); } catch (Exception e) { e.printStackTrace(); } owner.destroy(true); GroupPublisherService.delRoomEvt(groupId, roomid); Jedis jedis0 =Redis.use("group1_db0").getJedis(); jedis0.del("room:"+roomid); jedis0.close(); } else if (owner.room.playerMapBySeat.containsKey(owner.seat)) { ITObject data = new TObject(); data.putInt("aid", owner.playerid); owner.room.broadCastToClient(owner.playerid, Router.GAME_EVT_PLAYER_EXIT, data); owner.destroy(true); } } } } /** * 玩家网络状态通知 * * @param owner */ public void playerNetState(Player owner) { ITObject param = new TObject(); param.putInt("aid", owner.playerid); param.putInt("online", owner.isConnect ? 1 : 0); owner.room.updatePlayerOffline(owner); owner.room.broadCastToClient(owner.playerid, Router.GAME_EVT_PLAYER_NET_STATE, param); } /** * 更新玩家GPS位置 * * @param owner */ public void updatePlayerPos(Player owner) { ITObject param = new TObject(); param.putInt("seat", owner.seat); param.putUtfString("pos", owner.gps_pos); owner.room.broadCastToClient(owner.playerid, Router.GAME_EVT_UPDATE_POS, param); } /** * 更新玩家托管 * * @param owner */ public void updatePlayerEntrust(Player owner) { ITObject param = new TObject(); param.putInt("aid", owner.playerid); param.putInt("type", 5); param.putBoolean("entrust", owner.entrust); owner.room.broadCastToClient(0, Router.GAME_EVT_UPDATE_PLAYERINFO, param); } /** * 删除房间 * * @param groupId * @param roomId * @return * @throws Exception */ public static final ITObject delRoom(int groupId, String roomId) throws Exception { String tag_key = "room:" + roomId; Jedis jedis0 = Redis.use("group1_db0").getJedis(); // String svr = StringUtil.Empty; RedisLock lock = new RedisLock(tag_key, jedis0); try { lock.lock(); List list = jedis0.hmget(tag_key, "AA", "payer", "pay", "group", "game", "status", "gpid", "fake", "players"); String status = list.get(5); int _status = Integer.parseInt(status); String group = list.get(3); int _gid = 0; if (StringUtil.isNotEmpty(group)) { _gid = Integer.parseInt(group); } String strGpid = list.get(6); int _gpid = 0; if (StringUtil.isNotEmpty(strGpid)) { _gpid = Integer.parseInt(strGpid); } String strFake = list.get(7); if (_status == 0) { if (strFake == null) { int gameId = Integer.parseInt(list.get(4)); boolean pay_AA = Integer.parseInt(list.get(0)) == 1; if (!pay_AA) { int payer = Integer.parseInt(list.get(1)); int pay = Integer.parseInt(list.get(2)); Utility.payDiamo(EventType.REDIS_EVENT_BACK_PAY, payer, gameId, pay, groupId, _gpid); } } } if (strFake != null) { try { ITArray players = TArray.newFromJsonData(list.get(8)); for (int i = 0; i < players.size(); i++) { int player_id = players.getInt(i); Redis.use("group1_db1").srem("used_robot", Integer.toString(player_id)); // Redis.use("group1_db1").sadd("free_robot", Integer.toString(player_id)); } } catch (Exception e) { } } jedis0.hset(tag_key, "status", "2"); BaseCache.updateCacheVer(jedis0, tag_key); GroupPublisherService.delRoomEvt(groupId, roomId); // svr = jedis0.hget(tag_key, "svr"); // // List server_ip = Redis.use("group1_db0").hmget(svr, "ip", "port"); // String ip = server_ip.get(0); // if(StringUtil.isEmpty(ip)) { // throw new WebException(ErrorCode.NO_SERVICE); // } // String port =server_ip.get(1); ITObject obj = TObject.newInstance(); // obj.putString("ip", ip); // obj.putInt("port", Integer.parseInt(port)); return obj; } finally { lock.unlock(); } } }