changhongserver/game_common/src/main/java/com/game/GameController.java

774 lines
22 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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<Integer, Player> 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<Integer, Player> 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<Integer, Player> 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<Player> 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<String> 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<String> 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();
}
}
}