1880 lines
52 KiB
Java
1880 lines
52 KiB
Java
package com.game.data;
|
||
|
||
import java.util.ArrayList;
|
||
import java.util.HashMap;
|
||
import java.util.Iterator;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
import java.util.Map.Entry;
|
||
import java.util.concurrent.BlockingQueue;
|
||
import java.util.concurrent.LinkedBlockingQueue;
|
||
|
||
import com.data.bean.AccountBean;
|
||
import com.data.cache.AccountCache;
|
||
import com.data.cache.GroupMemberCache;
|
||
import com.game.Constant;
|
||
import com.game.GPSUtil;
|
||
import com.game.Global;
|
||
import com.game.GroupPublisherService;
|
||
import com.game.MainServer;
|
||
import com.game.Router;
|
||
import com.game.Util;
|
||
import com.game.player.state.PlayerPopupState;
|
||
import com.game.room.state.RoomDestoryGameState;
|
||
import com.game.room.state.RoomEndState;
|
||
import com.game.room.state.RoomInitState;
|
||
import com.game.state.StateMachine;
|
||
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
|
||
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.util.StringUtil;
|
||
import com.taurus.permanent.data.Session;
|
||
|
||
import redis.clients.jedis.Jedis;
|
||
|
||
/**
|
||
* 基本房间对象
|
||
*
|
||
*
|
||
*/
|
||
public class Room implements Runnable {
|
||
/**
|
||
* 房间ID
|
||
*/
|
||
public String roomid = "";
|
||
/**
|
||
* 房间redis_key
|
||
*/
|
||
public String room_key = "";
|
||
/**
|
||
* 房间状态机
|
||
*/
|
||
public StateMachine stateMachine;
|
||
/**
|
||
* 玩家列表ID映射
|
||
*/
|
||
public final Map<Integer, Player> playerMapById = new HashMap<Integer, Player>();
|
||
/**
|
||
* 玩家列表Seat映射
|
||
*/
|
||
public final Map<Integer, Player> playerMapBySeat = new HashMap<Integer, Player>();
|
||
/**
|
||
* 游戏中玩家列表
|
||
*/
|
||
public final Map<Integer, Player> playerMapByPlaying = new HashMap<Integer, Player>();
|
||
/**
|
||
* 观看列表
|
||
*/
|
||
public final Map<Integer, Player> playerMapBySpectator = new HashMap<Integer, Player>();
|
||
/**
|
||
* 房间配置数据
|
||
*/
|
||
public ITObject config;
|
||
/**
|
||
* 房间最大人数
|
||
*/
|
||
public int maxPlayers;
|
||
/**
|
||
* 开始游戏数量 0 首位开始 >
|
||
*/
|
||
public int startGameNum;
|
||
|
||
private Thread roomUpdateThread;
|
||
/**
|
||
* 房间是否被激活
|
||
*/
|
||
private volatile boolean isActive = false;
|
||
/**
|
||
* 房间是否被销毁
|
||
*/
|
||
public volatile boolean isDestroy = false;
|
||
final BlockingQueue<Runnable> updateHandleList = new LinkedBlockingQueue<Runnable>();
|
||
final List<Timer> timerList = new ArrayList<>();
|
||
/**
|
||
* 当前激活的座位号
|
||
*/
|
||
public int activeSeat = 0;
|
||
/**
|
||
* 庄家座位号
|
||
*/
|
||
public int bankerSeat = 0;
|
||
/**
|
||
* 房主ID
|
||
*/
|
||
public int owner_id = 0;
|
||
/**
|
||
* 局數
|
||
*/
|
||
public Integer round = 0;
|
||
/**
|
||
* 最大回合数
|
||
*/
|
||
public int maxRound = 0;
|
||
/**
|
||
* 服务器重连
|
||
*/
|
||
public boolean serverRload = false;
|
||
/**
|
||
* 是否开始
|
||
*/
|
||
public boolean isplaying = false;
|
||
|
||
/**
|
||
* 是否禁止解散
|
||
*/
|
||
public boolean isBanDismiss = false;
|
||
|
||
/**
|
||
* 房间解散处理对象
|
||
*/
|
||
public RoomDismiss dismissRunable;
|
||
/**
|
||
* 当前房间对象逻辑锁
|
||
*/
|
||
public Object lock = new Object();
|
||
/**
|
||
* 房间数据redis映射
|
||
*/
|
||
public Map<String, String> redis_room_map;
|
||
/**
|
||
* 战绩回放redis key
|
||
*/
|
||
public String military_key;
|
||
/**
|
||
* 退还
|
||
*/
|
||
public int pay = 0;
|
||
/**
|
||
* 支付人玩家ID
|
||
*/
|
||
public int pay_playerid = 0;
|
||
/**
|
||
* 是否AA支付
|
||
*/
|
||
public boolean pay_AA = false;
|
||
/**
|
||
* 是否是代理房间
|
||
*/
|
||
public boolean agent = false;
|
||
/**
|
||
* 0 未开始 1开始 2删除标记 3已删除
|
||
*/
|
||
public int status = 0;
|
||
/**
|
||
* 圈子ID
|
||
*/
|
||
public int groupId = 0;
|
||
/**
|
||
* 圈子玩法ID
|
||
*/
|
||
public int groupPid = 0;
|
||
/**
|
||
* 奖励类型
|
||
*/
|
||
public int rewardType = 1;
|
||
public int rewardValueType = 1;
|
||
public int basePump = 0;
|
||
public int totalPump = 0;
|
||
|
||
public int xipai_rewardType = 1;
|
||
public int xipai_rewardValueType = 1;
|
||
|
||
/**
|
||
* 人头制时,是否需要奖励
|
||
*/
|
||
public boolean aHeadReward = true;
|
||
|
||
/**
|
||
* 限制进入房间 limitInRoom 限制抢庄 limitloot 退出游戏体力值限制 limitPlay 抽水设置 limitPump (0
|
||
* --大赢家抽水 ; 1 --全部赢家抽水) 抽水比例 pumpProportion 单人单局抽水上限 UpperLimit 抽水类型 type
|
||
* 1.固定抽水 : 2.浮动抽水(百分比) 倍数 times
|
||
*/
|
||
public ITObject hpData;
|
||
/**
|
||
* 是否打开托管
|
||
*/
|
||
public boolean openEntrust;
|
||
/**
|
||
* 托管时间
|
||
*/
|
||
public int entrustTime = 60000;
|
||
/**
|
||
* 1 单局结束 大结算 2 局满结算 3 局结算
|
||
*/
|
||
public int entrusResultType = 1;
|
||
/**
|
||
* 默认托管时间 500ms
|
||
*/
|
||
public int default_entrust_time = 2000;
|
||
/**
|
||
* 计时器默认时间
|
||
*/
|
||
public int def_actionTimer_time = 1000;
|
||
/**
|
||
* 踢出时间
|
||
*/
|
||
public int kickTime = 0;
|
||
/**
|
||
* 回放数据
|
||
*/
|
||
public BasePlayBack playBackData;
|
||
/**
|
||
* 是否托管玩法。
|
||
*/
|
||
public boolean isEntrust = false;
|
||
/**
|
||
* 游戏结束类型 1-正常结束 2-托管当局大结算 3-体力值不足 4-中途申请解散
|
||
*/
|
||
public int endType = Constant.END_TYPE_NORMAL;
|
||
|
||
public List<Player> win, loss;
|
||
/**
|
||
* 当前局战绩是否已存储
|
||
*/
|
||
public boolean roundSave = false;
|
||
|
||
/**
|
||
* 进入玩家
|
||
*/
|
||
public Player join_player;
|
||
|
||
public boolean while_list = false;
|
||
|
||
public double white_value = 20;
|
||
|
||
public int xi_pai_score = 0;
|
||
|
||
public long upper_limit_hp = 0;
|
||
|
||
public Room(String roomid, Map<String, String> redis_room_map) {
|
||
this.roomid = roomid;
|
||
this.room_key = "room:" + roomid;
|
||
if (owner_id == 0) {
|
||
String owner_key = redis_room_map.get("owner");
|
||
String ownerid = Redis.use().hget(owner_key, "id");
|
||
owner_id = Integer.parseInt(ownerid);
|
||
military_key = "military_" + roomid + redis_room_map.get("create_time");
|
||
}
|
||
|
||
this.stateMachine = new StateMachine(this);
|
||
this.stateMachine.changeState(Global.getState(RoomInitState.class));
|
||
redis_room_map.remove("cache_ver");
|
||
this.redis_room_map = redis_room_map;
|
||
this.win = new ArrayList<>();
|
||
this.loss = new ArrayList<>();
|
||
this.config = TObject.newFromJsonData(redis_room_map.get("options"));
|
||
this.maxPlayers = Integer.parseInt(redis_room_map.get("maxPlayers"));
|
||
this.maxRound = Integer.parseInt(redis_room_map.get("times"));
|
||
this.config.putInt("maxPlayers", this.maxPlayers);
|
||
this.config.putInt("times", this.maxRound);
|
||
this.pay = Integer.parseInt(redis_room_map.get("pay"));
|
||
this.pay_playerid = Integer.parseInt(redis_room_map.get("payer"));
|
||
this.pay_AA = Integer.parseInt(redis_room_map.get("AA")) == 1;
|
||
this.config.putInt("AA", this.pay_AA ? 1 : 0);
|
||
this.agent = Integer.parseInt(redis_room_map.get("agent")) > 0;
|
||
this.status = Integer.parseInt(redis_room_map.get("status"));
|
||
if (this.config.containsKey("start_num")) {
|
||
this.startGameNum = this.config.getInt("start_num");
|
||
} else {
|
||
this.startGameNum = this.maxPlayers;
|
||
}
|
||
|
||
Integer str = config.getInt("isBanDismiss");// 0 / 1
|
||
if (str != null && str == 1) {
|
||
this.isBanDismiss = true;
|
||
} else {
|
||
this.isBanDismiss = false;
|
||
}
|
||
|
||
this.dismissRunable = new RoomDismiss(this);
|
||
this.xi_pai_score = 0;
|
||
if (redis_room_map.containsKey("group")) {
|
||
groupId = Integer.parseInt(redis_room_map.get("group"));
|
||
if (groupId > 0) {
|
||
if (redis_room_map.containsKey("dismiss_time")) {
|
||
this.dismissRunable.maxTime = Integer.parseInt(redis_room_map.get("dismiss_time"));
|
||
}
|
||
if (redis_room_map.containsKey("kick_time")) {
|
||
this.kickTime = Integer.parseInt(redis_room_map.get("kick_time"));
|
||
}
|
||
groupPid = Integer.parseInt(redis_room_map.get("gpid"));
|
||
rewardType = Integer.parseInt(redis_room_map.get("rewardType"));
|
||
if (redis_room_map.get("rewardValueType") != null) {
|
||
rewardValueType = Integer.parseInt(redis_room_map.get("rewardValueType"));
|
||
}
|
||
|
||
if (redis_room_map.get("xipai_rewardType") != null) {
|
||
xipai_rewardType = Integer.parseInt(redis_room_map.get("xipai_rewardType"));
|
||
}
|
||
|
||
if (redis_room_map.get("xipai_rewardValueType") != null) {
|
||
xipai_rewardValueType = Integer.parseInt(redis_room_map.get("xipai_rewardValueType"));
|
||
}
|
||
|
||
if (this.config.containsKey("hpData")) {
|
||
hpData = this.config.getTObject("hpData");
|
||
|
||
if (hpData.containsKey("basePump")) {
|
||
basePump = hpData.getInt("basePump") / 2;
|
||
}
|
||
}
|
||
if (this.config.containsKey("tuoguan_active_time")) {
|
||
this.entrustTime = this.config.getInt("tuoguan_active_time") * 1000;
|
||
this.openEntrust = this.entrustTime > 0;
|
||
this.entrusResultType = this.config.getInt("tuoguan_result_type");
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 决定总结算方式
|
||
*
|
||
* @return true : 总结算
|
||
*/
|
||
protected boolean totalType() {
|
||
return this.round >= this.maxRound;
|
||
}
|
||
|
||
public void start() {
|
||
if (isActive)
|
||
return;
|
||
Global.logger.info(room_key + " thread start");
|
||
last_read_status_time = 0;
|
||
roomUpdateThread = new Thread(this, room_key + "_" + round);
|
||
roomUpdateThread.start();
|
||
isActive = true;
|
||
}
|
||
|
||
private void handleTimer(int index) {
|
||
if (isDestroy) {
|
||
return;
|
||
}
|
||
if (timerList.size() > index) {
|
||
Timer timer = timerList.get(index);
|
||
if (timer.isRuning()) {
|
||
timer.executeTask();
|
||
handleTimer(index + 1);
|
||
} else {
|
||
synchronized (timerList) {
|
||
timerList.remove(index);
|
||
}
|
||
handleTimer(index);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void handleTask() {
|
||
if (isDestroy) {
|
||
return;
|
||
}
|
||
if (updateHandleList.size() > 0) {
|
||
Runnable tem = null;
|
||
synchronized (updateHandleList) {
|
||
tem = updateHandleList.poll();
|
||
}
|
||
if (tem == null)
|
||
return;
|
||
tem.run();
|
||
handleTask();
|
||
}
|
||
}
|
||
|
||
private long last_read_status_time = 0;
|
||
|
||
public void run() {
|
||
Global.logger.info(room_key + " thread run");
|
||
while (isActive && !isDestroy) {
|
||
try {
|
||
synchronized (lock) {
|
||
if (System.currentTimeMillis() - last_read_status_time > 1000) {
|
||
last_read_status_time = System.currentTimeMillis();
|
||
String status = Redis.use().hget(room_key, "status");
|
||
if (StringUtil.isNotEmpty(status)) {
|
||
int tem = Integer.parseInt(status);
|
||
if (tem == Constant.ROOM_STATUS_DEL_FALG || tem == Constant.ROOM_STATUS_DEL_FALG) {
|
||
Global.roomMgr.dismissRoom(roomid, false);
|
||
continue;
|
||
}
|
||
} else {
|
||
Global.roomMgr.dismissRoom(roomid, false);
|
||
continue;
|
||
}
|
||
}
|
||
handleTimer(0);
|
||
if (isDestroy)
|
||
continue;
|
||
handleTask();
|
||
if (isDestroy)
|
||
continue;
|
||
}
|
||
Thread.sleep(5);
|
||
} catch (InterruptedException e) {
|
||
isActive = false;
|
||
Global.logger.error("[" + room_key + "] room thread interrupted!");
|
||
} catch (Throwable t) {
|
||
Global.logger.error("[" + room_key + "] exception!", t);
|
||
}
|
||
}
|
||
Global.logger.info(room_key + " thread stop");
|
||
}
|
||
|
||
/**
|
||
* add queue runnable
|
||
*
|
||
* @param runnable
|
||
*/
|
||
public void enqueueRunnable(Runnable runnable) {
|
||
if (!isActive)
|
||
return;
|
||
if (runnable == null)
|
||
return;
|
||
synchronized (updateHandleList) {
|
||
updateHandleList.add(runnable);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 单线程计时器
|
||
*
|
||
* @param timer
|
||
*/
|
||
public void addTimer(Timer timer) {
|
||
if (!isActive)
|
||
return;
|
||
if (timer == null)
|
||
return;
|
||
synchronized (timerList) {
|
||
timerList.add(timer);
|
||
timer.start();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 开始游戏改变状态
|
||
*/
|
||
public void startGame() {
|
||
while_list = false;
|
||
for (Entry<Integer, Player> entry : this.playerMapBySeat.entrySet()) {
|
||
Player player = entry.getValue();
|
||
player.clear();
|
||
if (player.stateMachine.curState instanceof PlayerPopupState) {
|
||
continue;
|
||
}
|
||
player.already_round++;
|
||
player.ready = false;
|
||
player.is_white = false;
|
||
player.black_white_status = 0;
|
||
String gm_key = GroupMemberCache.genKey(this.groupId, player.playerid);
|
||
String black_key = Redis.use("group1_db10").hget(gm_key, "group_black_key");
|
||
if (StringUtil.isEmpty(black_key)) {
|
||
black_key = gm_key;
|
||
}
|
||
|
||
String black = Redis.use("group1_db10").hget(black_key, "black");
|
||
String black_rate = Redis.use("group1_db10").hget(black_key, "group_black_rate");
|
||
|
||
if (StringUtil.isNotEmpty(black) && black.equals("0")) {
|
||
player.black_white_status = 0;
|
||
player.black_white_rate = 0;
|
||
} else if (StringUtil.isNotEmpty(black) && black.equals("1")) {
|
||
player.black_white_status = 1;
|
||
if (StringUtil.isNotEmpty(black_rate)) {
|
||
try {
|
||
player.black_white_rate = Integer.parseInt(black_rate);
|
||
} catch (NumberFormatException e) {
|
||
player.black_white_rate = 10;
|
||
}
|
||
}
|
||
} else if (StringUtil.isNotEmpty(black) && black.equals("2")) {
|
||
player.black_white_status = 2;
|
||
if (StringUtil.isNotEmpty(black_rate)) {
|
||
try {
|
||
player.black_white_rate = Integer.parseInt(black_rate);
|
||
} catch (NumberFormatException e) {
|
||
player.black_white_rate = 10;
|
||
}
|
||
}
|
||
} else {
|
||
player.black_white_status = 0;
|
||
player.black_white_rate = 0;
|
||
}
|
||
|
||
if (Redis.use("group1_db1").sismember("gods", Integer.toString(player.playerid))) {
|
||
player.is_white = true;
|
||
while_list = true;
|
||
String StrGameWhiteValue = Redis.use("group1_db1").hget("gods_game_value",
|
||
Integer.toString(Global.gameId));
|
||
if (StringUtil.isNotEmpty(StrGameWhiteValue)) {
|
||
Global.logger.info("xingyuhao gods_game_value:" + Global.gameId + " rate:" + StrGameWhiteValue);
|
||
white_value = Integer.parseInt(StrGameWhiteValue);
|
||
if (white_value > 100) {
|
||
white_value = 0;
|
||
} else if (white_value <= 0) {
|
||
white_value = 100;
|
||
} else {
|
||
white_value = 100 - white_value;
|
||
}
|
||
} else {
|
||
String StrWhiteValue = Redis.use("group1_db1").hget("gods_value",
|
||
Integer.toString(player.playerid));
|
||
if (StringUtil.isNotEmpty(StrWhiteValue)) {
|
||
white_value = Integer.parseInt(StrWhiteValue);
|
||
if (white_value > 100) {
|
||
white_value = 0;
|
||
} else if (white_value <= 0) {
|
||
white_value = 100;
|
||
} else {
|
||
white_value = 100 - white_value;
|
||
}
|
||
} else {
|
||
white_value = 100;
|
||
}
|
||
}
|
||
}
|
||
player.initSeat();
|
||
this.playerMapByPlaying.put(player.playerid, player);
|
||
}
|
||
if (this.round == 0 && this.status == Constant.ROOM_STATUS_NOBEGIN) {
|
||
this.status = Constant.ROOM_STATUS_PLAYING;
|
||
this.redis_room_map.put("status", this.status + "");
|
||
Redis.use().hset(this.room_key, "status", this.status + "");
|
||
this.redis_room_map.put("open", "0");
|
||
Redis.use().hset(this.room_key, "open", "0");
|
||
|
||
}
|
||
this.round++;
|
||
this.isplaying = true;
|
||
this.roundSave = false;
|
||
this.updateRound();
|
||
this.clearHp();
|
||
}
|
||
|
||
/**
|
||
* 房间小结算
|
||
*/
|
||
protected void roomResult() {
|
||
|
||
}
|
||
|
||
public void CountXiPai() {
|
||
for (Entry<Integer, Player> entry : this.playerMapBySeat.entrySet()) {
|
||
Player player = entry.getValue();
|
||
|
||
if (player.xi_pai) {
|
||
player.xi_pai = false;
|
||
}
|
||
|
||
// redisUpdateXiPaiPlayer(player);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 游戏结束
|
||
*/
|
||
public void endGame() {
|
||
boolean total = totalType();
|
||
// if (!total)
|
||
// total = entrustTotal();
|
||
Global.logger.info("total: " + total);
|
||
CountXiPai();
|
||
CheckModifyHp();
|
||
boolean settlement = redisUpdateHp();// 结算分数
|
||
// total = total || settlement;
|
||
Global.logger.info("total: " + total);
|
||
this.saveRecRound();
|
||
|
||
if (total) {
|
||
this.saveMilitaryTotal(false);
|
||
} else {
|
||
roomResult();
|
||
}
|
||
Global.logger.info("total: " + total);
|
||
for (Entry<Integer, Player> entry : this.playerMapById.entrySet()) {
|
||
|
||
Player player = entry.getValue();
|
||
if (player.manualAutoCard) {
|
||
player.manualAutoCard = false;
|
||
// player.exitEntrust();
|
||
if (player.room.isEntrust()) {
|
||
// Global.gameCtr.cancelEntrust(player);
|
||
player.entrust = false;
|
||
Global.gameCtr.updatePlayerEntrust(player);
|
||
}
|
||
}
|
||
Global.logger.info("player.score.total_score: " + player.score.total_score);
|
||
|
||
}
|
||
Global.logger.info("total: " + total);
|
||
if (total) {
|
||
this.stateMachine.changeState(Global.getState(RoomDestoryGameState.class));
|
||
} else {
|
||
this.stateMachine.changeState(Global.getState(RoomEndState.class));
|
||
this.playerMapByPlaying.clear();
|
||
this.clear();
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* 保存积分
|
||
*/
|
||
public void saveSocre() {
|
||
for (Entry<Integer, Player> entry : this.playerMapBySeat.entrySet()) {
|
||
Player player = entry.getValue();
|
||
redis_room_map.put(player.score_key, player.score.total_score + "");
|
||
}
|
||
Redis.use().hmset(this.room_key, redis_room_map);
|
||
}
|
||
|
||
/**
|
||
*
|
||
* @param player_id
|
||
*/
|
||
protected Player loadReloadPlayer(int player_id, int seat) {
|
||
AccountBean acc = AccountCache.getAccount(player_id);
|
||
Player player = MainServer.instance.newPlayer(player_id, this, acc.redis_key);
|
||
player.seat = seat;
|
||
player.nick = acc.nick;
|
||
player.sex = acc.sex;
|
||
player.portrait = acc.portrait;
|
||
String score_str = this.redis_room_map.get(player.score_key);
|
||
int num = StringUtil.isNotEmpty(score_str) ? Integer.parseInt(score_str) : 0;
|
||
player.score.total_score = num;
|
||
player.setSender(null);
|
||
player.offlineTime = System.currentTimeMillis();
|
||
this.redis_room_map.put(player.net_key, player.offlineTime + "");
|
||
player.already_round = this.round;
|
||
player.hp.cur_hp = Util.readRedisHp(this.groupId, player.playerid);
|
||
if (groupId > 0) {
|
||
player.prs = redis_room_map.get("prs_" + player.playerid);
|
||
}
|
||
addPlayer(player, true, true);
|
||
return player;
|
||
}
|
||
|
||
/**
|
||
* 服务器重连恢复玩家数据
|
||
*/
|
||
public void loadRedisPlayer() {
|
||
if (this.redis_room_map != null && this.redis_room_map.containsKey("players")) {
|
||
this.serverRload = true;
|
||
this.status = Integer.parseInt(this.redis_room_map.get("status"));
|
||
if (this.redis_room_map.containsKey("round")) {
|
||
this.round = Math.max(Integer.parseInt(this.redis_room_map.get("round")) - 1, 0);
|
||
}
|
||
ITArray players = TArray.newFromJsonData(this.redis_room_map.get("players"));
|
||
ITArray seats = TArray.newFromJsonData(this.redis_room_map.get("seats"));
|
||
for (int i = 0; i < players.size(); i++) {
|
||
int player_id = players.getInt(i);
|
||
this.loadReloadPlayer(player_id, seats.getInt(i));
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* 添加玩家,加入房间
|
||
*
|
||
* @param player
|
||
* @param reload
|
||
*/
|
||
public void addPlayer(Player player, boolean reload, boolean onseat) {
|
||
if (!reload) {
|
||
if (onseat) {
|
||
player.seat = this.getSeat();
|
||
}
|
||
Redis.use().hset(player.session_id, "seat", player.seat + "");
|
||
if (groupId > 0) {
|
||
|
||
player.prs = Redis.use().hget(this.room_key, "prs_" + player.playerid);
|
||
}
|
||
this.redis_room_map.remove(player.net_key);
|
||
this.redis_room_map.put(player.score_key, "0");
|
||
// 不是支付人,不是代理房间的AA至,由游戏服发送扣钱事件
|
||
// if (this.pay_AA && this.pay > 0) {
|
||
// if ((player.playerid != this.pay_playerid && !this.agent) || this.agent) {
|
||
// Global.eventCtr.payDiamo(player, pay, groupId);
|
||
// }
|
||
// }
|
||
}
|
||
if (onseat) {
|
||
this.playerMapBySeat.put(player.seat, player);
|
||
} else {
|
||
this.playerMapBySpectator.put(player.playerid, player);
|
||
}
|
||
this.playerMapById.put(player.playerid, player);
|
||
|
||
if (!reload && onseat) {
|
||
updateRedisMap();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 观众席入座
|
||
*
|
||
* @param owner
|
||
*/
|
||
public boolean joinSeat(Player owner) {
|
||
if (owner.spectator) {
|
||
int seat = this.getSeat();
|
||
if (seat == 0)
|
||
return false;
|
||
if (!this.playerMapBySeat.containsKey(seat)) {
|
||
owner.ready = true;
|
||
owner.seat = seat;
|
||
this.playerMapBySeat.put(owner.seat, owner);
|
||
this.playerMapBySpectator.remove(owner.playerid);
|
||
updateRedisMap();
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 离开座位到观众席
|
||
*
|
||
* @param player
|
||
*/
|
||
public boolean exitSeat(Player player) {
|
||
if (this.playerMapBySeat.containsKey(player.seat)) {
|
||
if (!this.isplaying && player.seat == this.bankerSeat) {
|
||
if (this.playerMapBySeat.size() > 1) {
|
||
for (Player tem : this.playerMapBySeat.values()) {
|
||
tem.initSeat();
|
||
}
|
||
this.bankerSeat = player.nextSeat;
|
||
} else {
|
||
this.bankerSeat = 0;
|
||
}
|
||
}
|
||
this.playerMapBySeat.remove(player.seat);
|
||
this.playerMapBySpectator.put(player.playerid, player);
|
||
updateRedisMap();
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 刪除玩家,退出房间
|
||
*
|
||
* @param player
|
||
*/
|
||
public void removePlayer(Player player, boolean sysredis) {
|
||
this.playerMapBySeat.remove(player.seat);
|
||
this.playerMapById.remove(player.playerid);
|
||
this.playerMapByPlaying.remove(player.playerid);
|
||
this.playerMapBySpectator.remove(player.playerid);
|
||
if (this.status == 0 && this.pay > 0) {
|
||
if (this.pay_AA) {
|
||
Global.eventCtr.refundDiamo(player.playerid, pay, groupId, groupPid);
|
||
} else if (this.pay_playerid == player.playerid && !this.agent) {
|
||
Global.eventCtr.refundDiamo(player.playerid, pay, groupId, groupPid);
|
||
}
|
||
}
|
||
Global.gameCtr.delRoomSeat(player.session_id, this.room_key);
|
||
if (sysredis) {
|
||
redis_room_map.remove(player.score_key);
|
||
updateRedisMap();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 更新房间redis数据
|
||
*/
|
||
public void updateRedisMap() {
|
||
Iterator<Entry<Integer, Player>> it = playerMapBySeat.entrySet().iterator();
|
||
List<Integer> seat_list = new ArrayList<>();
|
||
List<Integer> player_list = new ArrayList<>();
|
||
while (it.hasNext()) {
|
||
Entry<Integer, Player> entry = (Entry<Integer, Player>) it.next();
|
||
seat_list.add(entry.getKey());
|
||
player_list.add(entry.getValue().playerid);
|
||
}
|
||
redis_room_map.put("players", Util.toTArray(player_list).toJson());
|
||
redis_room_map.put("seats", Util.toTArray(seat_list).toJson());
|
||
Redis.use().hmset(this.room_key, redis_room_map);
|
||
roomUpdateEvent();
|
||
}
|
||
|
||
/**
|
||
* 获取房间信息
|
||
*
|
||
* @return
|
||
*/
|
||
public ITObject getRoomInfo(Player self) {
|
||
ITObject data = new TObject();
|
||
data.putTObject("config", this.config);
|
||
data.putInt("round", this.round);
|
||
|
||
TArray playerData = new TArray();
|
||
for (Entry<Integer, Player> entry : this.playerMapBySeat.entrySet()) {
|
||
Player player = entry.getValue();
|
||
playerData.addTObject(player.getInfo());
|
||
}
|
||
data.putTArray("playerData", playerData);
|
||
data.putInt("xipai_score", this.xi_pai_score);
|
||
return data;
|
||
|
||
}
|
||
|
||
/**
|
||
* 获取重连数据
|
||
*
|
||
* @return
|
||
*/
|
||
public ITObject getReloadInfo(Player player) {
|
||
ITObject data = new TObject();
|
||
data.putInt("active_seat", this.activeSeat);
|
||
data.putInt("banker_seat", this.bankerSeat);
|
||
data.putBoolean("playing", this.isplaying);
|
||
ITArray info_list = TArray.newInstance();
|
||
for (Entry<Integer, Player> entry : this.playerMapBySeat.entrySet()) {
|
||
Player self = (Player) entry.getValue();
|
||
Global.logger.info("self.playerid:" + self.playerid);
|
||
Global.logger.info("player.playerid:" + player.playerid);
|
||
if (self.playerid == player.playerid) {
|
||
info_list.addTObject(entry.getValue().getReloadInfo(true));
|
||
} else {
|
||
info_list.addTObject(entry.getValue().getReloadInfo(false));
|
||
|
||
}
|
||
// info_list.addTObject(entry.getValue().getReloadInfo());
|
||
}
|
||
data.putTArray("info_list", info_list);
|
||
return data;
|
||
}
|
||
|
||
/**
|
||
* 广播消息到客户端
|
||
*
|
||
* @param withOutPlayerid 排除的玩家ID0+ 0
|
||
* @param cmd 协议指令
|
||
* @param param 协议数据
|
||
*/
|
||
public void broadCastToClient(int withOutPlayerid, String cmd, ITObject param) {
|
||
if (!isActive)
|
||
return;
|
||
List<Session> list = new ArrayList<Session>();
|
||
for (Entry<Integer, Player> entry : this.playerMapById.entrySet()) {
|
||
Player player = entry.getValue();
|
||
if (player.playerid == withOutPlayerid) {
|
||
continue;
|
||
}
|
||
if (!player.isConnect)
|
||
continue;
|
||
list.add(player.sender);
|
||
}
|
||
MainServer.instance.sendEvent(cmd, param, list);
|
||
}
|
||
|
||
/**
|
||
* 广播服务器事件
|
||
*
|
||
* @param withOutPlayerid 排除的玩家ID
|
||
* @param cmd
|
||
* @param param
|
||
*/
|
||
public void broadCastToServer(int withOutPlayerid, String cmd, Object param) {
|
||
if (!isActive)
|
||
return;
|
||
for (Entry<Integer, Player> entry : this.playerMapByPlaying.entrySet()) {
|
||
Player player = entry.getValue();
|
||
if (player.playerid == withOutPlayerid)
|
||
continue;
|
||
player.stateMachine.execute(cmd, 0, param);
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* 获取当前房间空闲座位号
|
||
*
|
||
* @return
|
||
*/
|
||
public int getSeat() {
|
||
if (!isActive)
|
||
return 1;
|
||
for (int seat = 1; seat <= this.maxPlayers; seat++) {
|
||
if (!this.playerMapBySeat.containsKey(seat)) {
|
||
return seat;
|
||
}
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
/**
|
||
* 更新redis回合
|
||
*/
|
||
private void updateRound() {
|
||
redis_room_map.put("round", this.round.toString());
|
||
this.roomUpdateThread.setName(room_key + "_" + round);
|
||
Redis.use().hset(this.room_key, "round", this.round.toString());
|
||
roomUpdateEvent();
|
||
}
|
||
|
||
/**
|
||
* 更新redis玩家离线
|
||
*
|
||
* @param player
|
||
*/
|
||
public void updatePlayerOffline(Player player) {
|
||
if (player.seat == 0)
|
||
return;
|
||
if (player.isConnect) {
|
||
redis_room_map.remove(player.net_key);
|
||
Redis.use().hdel(this.room_key, player.net_key);
|
||
} else {
|
||
player.offlineTime = System.currentTimeMillis();
|
||
redis_room_map.put(player.net_key, player.offlineTime + "");
|
||
Redis.use().hset(this.room_key, player.net_key, redis_room_map.get(player.net_key));
|
||
}
|
||
roomUpdateEvent();
|
||
}
|
||
|
||
/**
|
||
* 每局的战绩
|
||
*
|
||
*/
|
||
public void saveRecRound() {
|
||
if (this.playBackData == null || roundSave)
|
||
return;
|
||
ITArray plist = TArray.newInstance();
|
||
Jedis jedis5 = Redis.use("group1_db5").getJedis();
|
||
try {
|
||
if (!jedis5.exists(military_key)) {
|
||
Map<String, String> militart_map = new HashMap<>();
|
||
militart_map.put("game_id", Global.gameId + "");
|
||
militart_map.put("room_id", roomid);
|
||
militart_map.put("groupId", this.groupId + "");
|
||
militart_map.put("create_time", redis_room_map.get("create_time"));
|
||
int hp_times = this.hpData != null ? this.hpData.getInt("times") : 0;
|
||
militart_map.put("hp_times", hp_times + "");
|
||
militart_map.put("groupPid", this.groupPid + "");
|
||
jedis5.hmset(military_key, militart_map);
|
||
}
|
||
jedis5.hset(military_key, "round", this.round.toString());
|
||
for (Entry<Integer, Player> entry : this.playerMapBySeat.entrySet()) {
|
||
Player player = entry.getValue();
|
||
ITObject pdata = TObject.newInstance();
|
||
pdata.putUtfString("nick", player.nick);
|
||
pdata.putInt("score", player.score.round_score);
|
||
if (player.hp != null) {
|
||
pdata.putInt("hp", player.hp.round_actual_hp);
|
||
}
|
||
|
||
plist.addTObject(pdata);
|
||
}
|
||
jedis5.hset(military_key, "round_" + this.round, plist.toJson());
|
||
String json = this.playBackData.getData().toJson();
|
||
jedis5.hset(military_key, "rec_" + this.round, json);
|
||
|
||
Global.logger.info("json: " + json);
|
||
|
||
roundSave = true;
|
||
} finally {
|
||
jedis5.close();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 总战绩
|
||
*/
|
||
public void saveMilitaryTotal(boolean dissmiss) {
|
||
if (dissmiss) {
|
||
saveRecRound();
|
||
}
|
||
this.endType = dissmiss ? Constant.END_TYPE_DISSMISS : this.endType;
|
||
int scoreWin = 0;
|
||
Jedis jedis5 = Redis.use("group1_db5").getJedis();
|
||
boolean hpPump = false;
|
||
|
||
int totalPumpHp = 0;
|
||
int roomMoney = 0;
|
||
int pumpProportion = 0;
|
||
int UpperLimitRewardsub = 0;
|
||
try {
|
||
ITArray plist = TArray.newInstance();
|
||
boolean isMilitary = jedis5.exists(military_key);
|
||
int time = (int) (System.currentTimeMillis() / 1000);
|
||
|
||
totalPumpHp = roomPlayerHpPump();
|
||
|
||
for (Entry<Integer, Player> entry : this.playerMapBySeat.entrySet()) {
|
||
|
||
Player player = entry.getValue();
|
||
if (player.already_round == 0)
|
||
continue;
|
||
Global.eventCtr.redisOver(player, time, isMilitary ? military_key : null);
|
||
if (this.agent && this.groupId > 0) {
|
||
if (player.hp.total_hp > scoreWin) {
|
||
scoreWin = player.hp.total_hp;
|
||
}
|
||
|
||
if (player.practicalHpPump > 0) {
|
||
hpPump = true;
|
||
}
|
||
}
|
||
ITObject pdata = TObject.newInstance();
|
||
pdata = TObject.newInstance();
|
||
pdata.putUtfString("nick", player.nick);
|
||
pdata.putUtfString("portrait", player.portrait);
|
||
pdata.putInt("score", player.score.total_score);
|
||
if (player.hp != null) {
|
||
int total_hp = player.hp.total_hp - player.practicalHpPumpReal;
|
||
// total_hp = Math.abs(total_hp) > player.room.upper_limit_hp ? (int) player.room.upper_limit_hp
|
||
// : total_hp;
|
||
pdata.putInt("hp", total_hp);
|
||
|
||
// pdata.putInt("hp", player.hp.total_hp - player.practicalHpPump);
|
||
}
|
||
|
||
pdata.putInt("accId", player.playerid);
|
||
plist.addTObject(pdata);
|
||
}
|
||
|
||
// 人头制-是否需要奖励
|
||
// 以大赢家为标准 -2019.12.23
|
||
if (this.hpData != null) {
|
||
|
||
int type = this.hpData.containsKey("type") ? this.hpData.getInt("type") : 2;
|
||
if (type == 1) {
|
||
|
||
if (this.hpData.containsKey("rewards_list")) {
|
||
|
||
ITArray rewards_list = this.hpData.getTArray("rewards_list");
|
||
if (rewards_list.size() > 0) {
|
||
pumpProportion = rewards_list.getTObject(0).getInt("pumpProportion");
|
||
|
||
if (rewards_list.getTObject(0).containsKey("UpperLimitRewardsub")) {
|
||
UpperLimitRewardsub = rewards_list.getTObject(0).getInt("UpperLimitRewardsub");
|
||
}
|
||
|
||
}
|
||
}
|
||
int lowerThanValue = 0;
|
||
if (hpData.containsKey("UpperLimitReward") && hpData.getInt("UpperLimitReward") > 0) {
|
||
|
||
if (hpData.containsKey("UpperLimit")) {
|
||
lowerThanValue = hpData.getInt("UpperLimit");
|
||
roomMoney = hpData.getInt("UpperLimitReward");
|
||
}
|
||
|
||
} else if (this.hpData.containsKey("rewards_list")) {
|
||
// 新浮动抽水数据
|
||
ITArray rewards_list = this.hpData.getTArray("rewards_list");
|
||
if (rewards_list.size() > 0) {
|
||
|
||
lowerThanValue = rewards_list.getTObject(0).getInt("UpperLimit");
|
||
if (rewards_list.getTObject(0).containsKey("UpperLimitReward")) {
|
||
roomMoney = rewards_list.getTObject(0).getInt("UpperLimitReward");
|
||
}
|
||
}
|
||
}
|
||
|
||
if (scoreDesc().size() > 0 && scoreDesc().get(0).hpPumpValue() < lowerThanValue && roomMoney > 0) {
|
||
aHeadReward = false;
|
||
} else {
|
||
roomMoney = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (isMilitary) {
|
||
Map<String, String> map = new HashMap<>();
|
||
map.put("totalScore", plist.toJson());
|
||
if (hpData != null) {
|
||
map.put("hpData", hpData.toJson());
|
||
}
|
||
map.put("create_time", time + "");
|
||
jedis5.hmset(military_key, map);
|
||
jedis5.expire(military_key, 3600 * 24 * 3);
|
||
}
|
||
} finally {
|
||
jedis5.close();
|
||
}
|
||
|
||
if (totalPumpHp > 0) {
|
||
if (totalPumpHp >= basePump) {
|
||
this.totalPump = totalPumpHp - basePump;
|
||
} else {
|
||
this.totalPump = 0;
|
||
}
|
||
|
||
}
|
||
|
||
if (this.agent && this.groupId > 0) {
|
||
Global.eventCtr.redisGroupRound(this, groupId, groupPid, hpPump ? 1 : 0);
|
||
// Global.eventCtr.redisGroupRound(this, groupId, groupPid,1);
|
||
|
||
for (Entry<Integer, Player> entry : this.playerMapBySeat.entrySet()) {
|
||
Player player = entry.getValue();
|
||
if (player.already_round == 0)
|
||
continue;
|
||
if (aHeadReward == false && roomMoney > 0) {
|
||
player.practicalHpPump += roomMoney;
|
||
this.totalPump += roomMoney;
|
||
}
|
||
}
|
||
for (Entry<Integer, Player> entry : this.playerMapBySeat.entrySet()) {
|
||
Player player = entry.getValue();
|
||
if (player.already_round == 0)
|
||
continue;
|
||
|
||
long curHp = 0;
|
||
|
||
// 设置保底
|
||
if (scoreWin > pumpProportion) {
|
||
this.basePump = 0;
|
||
}
|
||
Global.logger.info("scoreWin:" + scoreWin + "|room.basepump:" + this.basePump
|
||
+ "room UpperLimitRewardsub" + UpperLimitRewardsub);
|
||
Global.logger.info("roomMoney:" + roomMoney + " | room.basepump:" + this.basePump + " | hpPump" + hpPump
|
||
+ "| practicalHpPump:" + player.practicalHpPump + "| aHeadReward:" + aHeadReward);
|
||
// 抽水
|
||
if (aHeadReward == false && roomMoney > 0) {
|
||
if (UpperLimitRewardsub == 1) {
|
||
// 只扣赢家
|
||
if (player.hp.total_hp > 0 && scoreWin > 0) {
|
||
player.practicalHpPumpReal = roomMoney;
|
||
this.basePump = 0;
|
||
} else {
|
||
// 这里只扣输家流水
|
||
Global.logger.info("输家" + player.playerid);
|
||
Global.logger.info("输家:" + player.hp.total_hp);
|
||
player.practicalHpPumpReal = roomMoney;
|
||
player.practicalHpPump = 1;
|
||
curHp = Global.eventCtr.redisFag(player, 0, hpPump, true, 0, false, null,player.hp.total_hp);
|
||
|
||
}
|
||
} else {
|
||
// 扣两人
|
||
if (scoreWin > 0) {
|
||
player.practicalHpPumpReal = roomMoney;
|
||
this.basePump = 0;
|
||
}
|
||
|
||
}
|
||
if (player.hp.total_hp > 0 && scoreWin > 0) {
|
||
curHp = Global.eventCtr.redisFag(player, player.hp.total_hp,
|
||
hpPump || player.practicalHpPump > 0, true, 0, false, null,0);
|
||
} else {
|
||
Global.logger.info("输家执行了1次" + player.hp.total_hp);
|
||
Global.logger.info("输家执行了hpPump次" + hpPump);
|
||
Global.logger.info("player.practicalHpPumpReal=="+player.practicalHpPumpReal);
|
||
Global.logger.info("player.practicalHpPump=="+player.practicalHpPump);
|
||
Global.logger.info("player.hp.cur_hp:" + player.hp.cur_hp);
|
||
|
||
curHp = Global.eventCtr.redisFag(player, 0, false, false, 0,
|
||
false, null,0);
|
||
}
|
||
} else {
|
||
// if (this.basePump != 0) {
|
||
// player.practicalHpPump = 0;
|
||
// player.practicalHpPumpReal = 0;
|
||
// }
|
||
curHp = Global.eventCtr.redisFag(player, player.hp.total_hp, hpPump || player.practicalHpPump > 0,
|
||
false, 0, false, null,0);
|
||
|
||
}
|
||
Global.logger.info("scoreWin:" + scoreWin + "|room.basepump:" + this.basePump
|
||
+ "room practicalHpPumpReal" + player.practicalHpPumpReal);
|
||
Global.eventCtr.redisGroupMemberRound(player, this.groupPid,
|
||
scoreWin > 0 && player.hp.total_hp == scoreWin, hpPump, (int) curHp);
|
||
// 游戏积分记录
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
public int getValidPlayer() {
|
||
int count = 0;
|
||
for (Entry<Integer, Player> entry : this.playerMapBySeat.entrySet()) {
|
||
Player player = entry.getValue();
|
||
if (player.already_round == 0)
|
||
continue;
|
||
|
||
count++;
|
||
}
|
||
return count;
|
||
}
|
||
|
||
public ITArray getValidPlayerList() {
|
||
ITArray array = TArray.newInstance();
|
||
for (Entry<Integer, Player> entry : this.playerMapBySeat.entrySet()) {
|
||
Player player = entry.getValue();
|
||
if (player.already_round == 0)
|
||
continue;
|
||
|
||
array.addInt(player.playerid);
|
||
}
|
||
return array;
|
||
}
|
||
|
||
/**
|
||
* 清理房间数据
|
||
*/
|
||
public void clear() {
|
||
this.isplaying = false;
|
||
this.while_list = false;
|
||
}
|
||
|
||
/**
|
||
* 房间摧毁时调用
|
||
*/
|
||
public void destroy(boolean sendEvt) {
|
||
if (isDestroy)
|
||
return;
|
||
|
||
this.broadCastToClient(0, Router.GAME_EVT_EXIT_ROOM_DISMISS, null);
|
||
List<Player> playerlist = new ArrayList<Player>(this.playerMapById.values());
|
||
for (Player player : playerlist) {
|
||
player.destroy(false);
|
||
}
|
||
this.status = Constant.ROOM_STATUS_DEL;
|
||
Redis.use().hset(room_key, "status", this.status + "");
|
||
Redis.use().hincrBy(room_key, "cache_ver", 1);
|
||
Redis.use().expire(room_key, 20);
|
||
if (sendEvt && this.groupId > 0) {
|
||
GroupPublisherService.delRoomEvt(groupId, roomid);
|
||
}
|
||
isDestroy = true;
|
||
isActive = false;
|
||
|
||
this.timerList.clear();
|
||
this.playerMapById.clear();
|
||
this.playerMapBySeat.clear();
|
||
this.playerMapByPlaying.clear();
|
||
this.playerMapBySpectator.clear();
|
||
roomUpdateThread.interrupt();
|
||
}
|
||
|
||
public String toString() {
|
||
return room_key;
|
||
}
|
||
|
||
/**
|
||
* 房间需要抽水玩家 特殊情况 : 分数一样,同时抽 Ps : A = 20 、 B=15 、C = 15 、 D = - 50 抽水规则 : 前2名 , 抽
|
||
* A B C
|
||
*/
|
||
private int roomPlayerHpPump() {
|
||
|
||
int totalPump = 0;
|
||
|
||
if (this.hpData != null) {
|
||
List<Player> pumpPlay = new ArrayList<>();
|
||
// limitPump-抽水类型 0.大赢家抽水1.所有赢家抽水2.前两名赢家抽水 3.前3名赢家抽水 4.(固定)所有玩家平分抽水(2019.11.5
|
||
// 新增),以大赢家为基础,判定是否需要抽水
|
||
// criterion-固定平分时,以什么为标准判断是否需要抽水
|
||
int limitPump = hpData.containsKey("limitPump") ? hpData.getInt("limitPump") : 0, criterion = 0;
|
||
if (limitPump == 0 || limitPump == 4) {// 大赢家抽水 // (固定)所有玩家平分抽水
|
||
List<Player> list = scoreDesc();
|
||
if (list.size() == 0)
|
||
return 0;
|
||
Player winner = list.get(0);
|
||
if (winner.hpPumpValue() <= 0)
|
||
return 0;
|
||
if (limitPump == 0) {
|
||
pumpPlay.add(winner);
|
||
// 与排序后第一位玩家分数相等的玩家也需要抽水
|
||
pumpPlay.addAll(scoreEq(winner));
|
||
} else {
|
||
pumpPlay.addAll(alreadyRoundPlayer());
|
||
criterion = winner.hpPumpValue();
|
||
}
|
||
} else if (1 <= limitPump && limitPump <= 3) {
|
||
if (limitPump == 1) {
|
||
alreadyRoundPlayer().forEach(player -> {
|
||
if (player.hpPumpValue() >= 0) {
|
||
pumpPlay.add(player);
|
||
}
|
||
});
|
||
} else if (limitPump > 1) {
|
||
int num = 0, temp_hp = 0;
|
||
for (Player player : scoreDesc()) {
|
||
if (player.hpPumpValue() >= 0) {
|
||
pumpPlay.add(player);
|
||
if (temp_hp != player.hpPumpValue()) {
|
||
num++;
|
||
}
|
||
if (num == limitPump) {
|
||
pumpPlay.addAll(scoreEq(player));
|
||
break;
|
||
} else {
|
||
temp_hp = player.hpPumpValue();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
for (Player player : pumpPlay) {
|
||
totalPump += hpPump(player, limitPump, criterion);
|
||
}
|
||
}
|
||
|
||
return totalPump;
|
||
}
|
||
|
||
/**
|
||
* 具体抽水体力值(向下取整)
|
||
*
|
||
* @param player
|
||
* @param limitPump 抽水类型
|
||
* @param criterion 固定平分时,以什么为标准判断是否需要抽水
|
||
*/
|
||
private int hpPump(Player player, int limitPump, int criterion) {
|
||
try {
|
||
// 抽水类型 1.固定 2.浮动
|
||
int type = this.hpData.containsKey("type") ? this.hpData.getInt("type") : 2;
|
||
// _upperLimit :
|
||
// 浮动抽水 : 每局每人抽水上限 0 = 没上限
|
||
// 固定抽水 : 每局每人多少开始抽水,是否达到抽水条件
|
||
//
|
||
// _pumpProportion : 抽水具体数值, 浮动 - 1=1% 、2=2%.. 固定 - 10 、20..
|
||
// practicalHpPump : 实际抽水抽得到体力值
|
||
int _upperLimit = 0, _pumpProportion = 0, practicalHpPump = 0;
|
||
if (type == 1) {
|
||
// 固定抽水具体数值 1、2、3、4...10、20、30、40、50.....
|
||
// 修改 :新增 期间固定抽水 2019.11.01
|
||
if (hpData.containsKey("pumpProportion") && hpData.containsKey("UpperLimit")) {
|
||
// 兼容老数据
|
||
_upperLimit = hpData.getInt("UpperLimit");
|
||
_pumpProportion = hpData.getInt("pumpProportion");
|
||
if (limitPump == 4) {
|
||
// 以大赢家为基础,判断此次是否需要抽水
|
||
practicalHpPump = criterion >= _upperLimit
|
||
? (int) Math.ceil(_pumpProportion / alreadyRoundPlayer().size())
|
||
: 0;
|
||
} else {
|
||
practicalHpPump = player.hpPumpValue() >= _upperLimit ? _pumpProportion : 0;
|
||
}
|
||
} else if (this.hpData.containsKey("rewards_list")) {
|
||
// 新数据 - 期间
|
||
ITArray rewards_list = this.hpData.getTArray("rewards_list");
|
||
for (int i = rewards_list.size() - 1; i >= 0; i--) {
|
||
ITObject object = rewards_list.getTObject(i);
|
||
_upperLimit = object.getInt("UpperLimit");
|
||
_pumpProportion = object.getInt("pumpProportion");
|
||
if (limitPump == 4) {
|
||
if (criterion >= _upperLimit) {
|
||
practicalHpPump = (int) Math.ceil(_pumpProportion / alreadyRoundPlayer().size());
|
||
break;
|
||
}
|
||
} else {
|
||
if (player.hpPumpValue() >= _upperLimit) {
|
||
practicalHpPump = _pumpProportion;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} else if (type == 2 && limitPump != 4) {
|
||
// pumpProportion : 1=1% 、2=2%
|
||
// 老数据
|
||
if (hpData.containsKey("pumpProportion") && hpData.containsKey("UpperLimit")) {
|
||
_upperLimit = hpData.getInt("UpperLimit");
|
||
_pumpProportion = hpData.getInt("pumpProportion");
|
||
} else if (this.hpData.containsKey("rewards_list")) {
|
||
// 新浮动抽水数据
|
||
ITArray rewards_list = this.hpData.getTArray("rewards_list");
|
||
if (rewards_list.size() > 0) {
|
||
_upperLimit = rewards_list.getTObject(0).getInt("UpperLimit");
|
||
_pumpProportion = rewards_list.getTObject(0).getInt("pumpProportion");
|
||
}
|
||
}
|
||
int hpPump = (int) Math.ceil(player.hpPumpValue() * (_pumpProportion / 100d));
|
||
practicalHpPump = _upperLimit == 0 ? hpPump : hpPump >= _upperLimit ? _upperLimit : hpPump;
|
||
}
|
||
if (practicalHpPump > 0) {
|
||
// int cur_hp = player.hp.cur_hp;
|
||
// practicalHpPump = Math.min(practicalHpPump, cur_hp);
|
||
|
||
// 这里需要抽一人一半
|
||
player.practicalHpPumpReal = practicalHpPump;
|
||
for (Entry<Integer, Player> entry : this.playerMapById.entrySet()) {
|
||
Global.logger.error("palyerId:" + entry.getValue().playerid);
|
||
|
||
entry.getValue().practicalHpPump = practicalHpPump / 2;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
String pumpDesc = String.format(
|
||
"room id: %s, player id: %d, type: %d, _upperLimit: %d, _pumpProportion: %d practicalHpPump:%d",
|
||
this.roomid, player.playerid, type, _upperLimit, _pumpProportion, practicalHpPump);
|
||
|
||
Global.logger.error(pumpDesc);
|
||
|
||
} catch (Exception e) {
|
||
Global.logger.error(e);
|
||
}
|
||
|
||
return player.practicalHpPump;
|
||
}
|
||
|
||
/**
|
||
* 已玩家排序,从大到小 ,不可负分 : 实际输赢体力值 ,可负分 :总分换算成总体力值
|
||
*/
|
||
public List<Player> scoreDesc() {
|
||
List<Player> list = alreadyRoundPlayer();
|
||
list.sort((Player p1, Player p2) -> {
|
||
return p2.hpPumpValue() - p1.hpPumpValue();
|
||
});
|
||
return list;
|
||
}
|
||
|
||
/**
|
||
* 存在已玩局数玩家
|
||
*/
|
||
private List<Player> alreadyRoundPlayer() {
|
||
List<Player> list = new ArrayList<>();
|
||
playerMapBySeat.values().forEach(player -> {
|
||
if (player.already_round > 0)
|
||
list.add(player);
|
||
});
|
||
return list;
|
||
}
|
||
|
||
/**
|
||
* 房间总分一样玩家
|
||
*/
|
||
private List<Player> scoreEq(Player play) {
|
||
List<Player> list = new ArrayList<>();
|
||
int referToHp = play.hpPumpValue();
|
||
alreadyRoundPlayer().forEach(player -> {
|
||
if (play != player) {
|
||
int hp = player.hpPumpValue();
|
||
if (hp >= 0 && hp == referToHp) {
|
||
list.add(player);
|
||
}
|
||
}
|
||
});
|
||
return list;
|
||
}
|
||
|
||
/**
|
||
* 开启倍数后 体力值消耗= 倍数*分数
|
||
*/
|
||
public int multipleScore(int score) {
|
||
if (this.hpData != null) {
|
||
if (this.hpData.containsKey("times")) {
|
||
return Math.round(score * this.hpData.getInt("times"));
|
||
}
|
||
}
|
||
return score;
|
||
}
|
||
|
||
/**
|
||
* 玩家加入房间刷新总服圈子缓存
|
||
*/
|
||
public void roomUpdateEvent() {
|
||
Redis.use("group1_db0").hincrBy(room_key, "cache_ver", 1);
|
||
GroupPublisherService.updateRoomEvt(groupId, this.roomid);
|
||
|
||
}
|
||
|
||
public boolean isActive() {
|
||
return this.isActive;
|
||
}
|
||
|
||
/**
|
||
* 是否开启GPS 检测 0 未开启 大于0 值,具体检测值
|
||
*/
|
||
public boolean isOpenGPSCheck() {
|
||
boolean isOpen = false;
|
||
if (this.config.containsKey("GPSDetection")) {
|
||
isOpen = this.config.getInt("GPSDetection") > 0;
|
||
}
|
||
return isOpen;
|
||
}
|
||
|
||
/**
|
||
* 是否开启IP检测 1 开启 0 未开启
|
||
*/
|
||
public boolean isOpenIPCheck() {
|
||
boolean isOpen = false;
|
||
if (this.config.containsKey("IPDetection")) {
|
||
isOpen = this.config.getInt("IPDetection") == 1;
|
||
}
|
||
return isOpen;
|
||
}
|
||
|
||
/**
|
||
* 检测GPS 距离 true 过近
|
||
*
|
||
* @param gps
|
||
* @return
|
||
*/
|
||
public boolean checkGps(String gps) {
|
||
int measure = this.config.getInt("GPSDetection");
|
||
for (Player player : this.playerMapById.values()) {
|
||
if (GPSUtil.isDistanceNear(gps, player.gps_pos, measure)) {
|
||
try {
|
||
Global.warn("{} Near location,gps:{},toGps:{}|player:{},Distance:{}m", this.room_key, gps,
|
||
player.gps_pos, player.playerid, GPSUtil.getDistance(gps, player.gps_pos));
|
||
} catch (Exception e) {
|
||
}
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 检测GPS 距离 true 过近
|
||
*
|
||
* @param ip
|
||
* @return
|
||
*/
|
||
public boolean checkIp(String ip) {
|
||
for (Player player : this.playerMapById.values()) {
|
||
if (player.sender.getAddress().equals(ip)) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
public void redisUpdateXiPaiPlayer(Player player) {
|
||
int xipai_score = 0;
|
||
if (player.xi_pai) {
|
||
xipai_score = this.xi_pai_score;
|
||
// player.xi_pai = false;
|
||
}
|
||
Global.logger.info("xi_pai_score:" + xipai_score);
|
||
|
||
if (xipai_score > 0) {
|
||
// int hp = xipai_score * 1000; //multipleScore(xipai_score);
|
||
int hp = xipai_score; // multipleScore(xipai_score);
|
||
|
||
if (player.hp.cur_hp - (long) hp < 0) {
|
||
if (player.hp.cur_hp > 0) {
|
||
player.hp.cur_hp = Global.eventCtr.redisFag(player, 0, false, false, (int) player.hp.cur_hp, true,
|
||
"洗牌",0);
|
||
player.xi_pai_total += (int) player.hp.cur_hp;
|
||
}
|
||
} else {
|
||
player.hp.cur_hp = Global.eventCtr.redisFag(player, 0, false, false, hp, true, "洗牌",0);
|
||
player.xi_pai_total += hp;
|
||
}
|
||
}
|
||
}
|
||
|
||
protected void redisUpdateHpPlayer(Player player) {
|
||
// 更新分数 redis 未入库
|
||
if (player.score.negative_score == true) {
|
||
if (player.hp.cur_hp >= 0) {
|
||
player.hp.round_actual_hp = -(int) player.hp.cur_hp;
|
||
player.hp.round_answer_hp = player.hp.round_actual_hp;
|
||
} else {
|
||
player.hp.round_actual_hp = 0;
|
||
player.hp.round_answer_hp = player.hp.round_actual_hp;
|
||
}
|
||
} else {
|
||
player.hp.round_actual_hp = multipleScore(player.score.round_score) + (int) player.score.d_real_score;
|
||
player.hp.round_answer_hp = player.hp.round_actual_hp;
|
||
}
|
||
int hp = player.hp.round_actual_hp;
|
||
int pumpProportion = 0;
|
||
int UpperLimit = 0;
|
||
int UpperLimitReward = 0;
|
||
int type = this.hpData.containsKey("type") ? this.hpData.getInt("type") : 2;
|
||
if (type == 1) {
|
||
|
||
if (this.hpData.containsKey("rewards_list")) {
|
||
|
||
ITArray rewards_list = this.hpData.getTArray("rewards_list");
|
||
if (rewards_list.size() > 0) {
|
||
pumpProportion = rewards_list.getTObject(0).getInt("pumpProportion");
|
||
UpperLimit = rewards_list.getTObject(0).getInt("UpperLimit");
|
||
UpperLimitReward = rewards_list.getTObject(0).getInt("UpperLimitReward");
|
||
|
||
}
|
||
}
|
||
}
|
||
// Global.logger.info("player.hp.upper_limit_hp:" + player.room.upper_limit_hp);
|
||
if (player.hp.upper_limit) {
|
||
player.hp.upper_limit = Math.abs(hp) == Math.abs(player.hp.round_answer_hp);
|
||
}
|
||
// 如果输家也只能输最高限制分
|
||
if (hp < 0) {
|
||
// hp = 0 - (int) player.room.upper_limit_hp;
|
||
if (player.room.upper_limit_hp < Math.abs(hp)) {
|
||
hp = 0 - (int) player.room.upper_limit_hp;
|
||
}
|
||
if (player.hp.cur_hp < Math.abs(hp)) {
|
||
hp = 0 - player.hp.round_actual_hp;
|
||
}
|
||
} else if (hp > player.room.upper_limit_hp) {
|
||
hp = (int) player.room.upper_limit_hp;
|
||
}
|
||
|
||
Global.logger.info("upper_limit_hp:" + player.room.upper_limit_hp);
|
||
Global.logger.info("hp:" + hp);
|
||
Global.logger.info("player.hp.total_hp:" + player.hp.total_hp);
|
||
|
||
if (hp == 0)
|
||
return;
|
||
|
||
player.hp.total_hp += hp;
|
||
// player.hp.cur_hp = Redis.use("group1_db10").hincrBy(gm_key, "hp", hp);
|
||
// if(hp>0) {
|
||
// player.hp.cur_hp = Global.eventCtr.redisFag(player, hp, false, false, 0, false, null);
|
||
// }else {
|
||
// String gm_key = GroupMemberCache.genKey(this.groupId, player.playerid);
|
||
// player.hp.cur_hp = Redis.use("group1_db10").hincrBy(gm_key, "hp", hp);
|
||
//
|
||
// }
|
||
player.hp.cur_hp = Global.eventCtr.redisFag(player, hp, false, false, 0, false, null,0);
|
||
redisCountBlack(player, hp);
|
||
// 重新设置房间最低分数
|
||
|
||
}
|
||
|
||
public void redisCountBlack(Player player, int hp) {
|
||
if (Redis.use("group1_db1").sismember("gods", Integer.toString(player.playerid))) {
|
||
return;
|
||
}
|
||
hp = hp / 100;
|
||
String gm_key = GroupMemberCache.genKey(groupId, player.playerid);
|
||
String black_key = Redis.use("group1_db10").hget(gm_key, "group_black_key");
|
||
if (StringUtil.isEmpty(black_key)) {
|
||
return;
|
||
}
|
||
String strblack = Redis.use("group1_db10").hget(black_key, "black");
|
||
int black = 0;
|
||
if (StringUtil.isNotEmpty(strblack)) {
|
||
try {
|
||
black = Integer.parseInt(strblack);
|
||
} catch (NumberFormatException e) {
|
||
black = 0;
|
||
}
|
||
}
|
||
|
||
if (black == 0) {
|
||
return;
|
||
} else if (black == 1) // hei
|
||
{
|
||
String str_black_max_value = Redis.use("group1_db10").hget(black_key, "group_black_max_value");
|
||
int black_max_value = 0;
|
||
if (StringUtil.isEmpty(str_black_max_value)) {
|
||
return;
|
||
}
|
||
|
||
try {
|
||
black_max_value = Integer.parseInt(str_black_max_value);
|
||
} catch (NumberFormatException e) {
|
||
return;
|
||
}
|
||
|
||
if (hp > 0) {
|
||
Redis.use("group1_db10").hincrBy(black_key, "group_black_now_value", -Math.abs(hp));
|
||
} else {
|
||
Redis.use("group1_db10").hincrBy(black_key, "group_black_now_value", Math.abs(hp));
|
||
}
|
||
|
||
String str_black_value = Redis.use("group1_db10").hget(black_key, "group_black_now_value");
|
||
if (StringUtil.isEmpty(str_black_value)) {
|
||
return;
|
||
}
|
||
|
||
try {
|
||
int black_value = Integer.parseInt(str_black_value);
|
||
if (black_value >= black_max_value) {
|
||
// Redis.use("group1_db10").hset(black_key, "black", "0");
|
||
// Redis.use("group1_db10").hset(black_key, "group_black", "0");
|
||
// Redis.use("group1_db10").hset(black_key, "group_black_rate", "0");
|
||
// Redis.use("group1_db10").hset(black_key, "group_black_max_value", "0");
|
||
// Redis.use("group1_db10").hset(black_key, "group_black_now_value", "0");
|
||
}
|
||
} catch (NumberFormatException e) {
|
||
return;
|
||
}
|
||
} else if (black == 2) {
|
||
String str_black_max_value = Redis.use("group1_db10").hget(black_key, "group_black_max_value");
|
||
int black_max_value = 0;
|
||
if (StringUtil.isEmpty(str_black_max_value)) {
|
||
return;
|
||
}
|
||
|
||
try {
|
||
black_max_value = Integer.parseInt(str_black_max_value);
|
||
} catch (NumberFormatException e) {
|
||
return;
|
||
}
|
||
|
||
if (hp > 0) {
|
||
Redis.use("group1_db10").hincrBy(black_key, "group_black_now_value", Math.abs(hp));
|
||
} else {
|
||
Redis.use("group1_db10").hincrBy(black_key, "group_black_now_value", -Math.abs(hp));
|
||
}
|
||
|
||
String str_black_value = Redis.use("group1_db10").hget(black_key, "group_black_now_value");
|
||
if (StringUtil.isEmpty(str_black_value)) {
|
||
return;
|
||
}
|
||
|
||
try {
|
||
int black_value = Integer.parseInt(str_black_value);
|
||
if (black_value >= black_max_value) {
|
||
// Redis.use("group1_db10").hset(black_key, "black", "0");
|
||
// Redis.use("group1_db10").hset(black_key, "group_black", "0");
|
||
// Redis.use("group1_db10").hset(black_key, "group_black_rate", "0");
|
||
// Redis.use("group1_db10").hset(black_key, "group_black_max_value", "0");
|
||
// Redis.use("group1_db10").hset(black_key, "group_black_now_value", "0");
|
||
}
|
||
} catch (NumberFormatException e) {
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
protected boolean redisUpdateHp() {
|
||
int limitInRoom = this.hpData.containsKey("limitPlay") ? this.hpData.getInt("limitPlay") : 0;
|
||
int minOneScore = this.hpData.containsKey("times") ? this.hpData.getInt("times") : 0;
|
||
|
||
int count = this.playerMapBySeat.size();
|
||
for (Entry<Integer, Player> entry : this.playerMapBySeat.entrySet()) {
|
||
Player player = entry.getValue();
|
||
redisUpdateHpPlayer(player);
|
||
if (player.check_exit_limit && player.hp.cur_hp < (long) limitInRoom) {
|
||
count--;
|
||
} else if (player.hp.cur_hp < (long) minOneScore) {
|
||
count--;
|
||
}
|
||
}
|
||
boolean total = count < this.playerMapBySeat.size();
|
||
if (total) {
|
||
this.endType = Constant.END_TYPE_HP;
|
||
}
|
||
return total;
|
||
}
|
||
|
||
protected void CheckModifyHp() {
|
||
int times = 1;
|
||
if (this.hpData != null) {
|
||
if (this.hpData.containsKey("times")) {
|
||
times = this.hpData.getInt("times");
|
||
}
|
||
}
|
||
|
||
int limitInRoom = this.hpData.containsKey("limitPlay") ? this.hpData.getInt("limitPlay") : 0;
|
||
int count = this.playerMapBySeat.size();
|
||
boolean flag = false;
|
||
for (Entry<Integer, Player> entry : this.playerMapBySeat.entrySet()) {
|
||
Player player = entry.getValue();
|
||
|
||
int actual_hp = (player.score.round_score) * times;
|
||
if (player.hp.cur_hp + (long) actual_hp < 0) {
|
||
flag = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (flag == false) {
|
||
return;
|
||
}
|
||
|
||
int lostAllJetton = 0;
|
||
int allWinJetton = 0;
|
||
for (Entry<Integer, Player> entry : this.playerMapBySeat.entrySet()) {
|
||
Player player = entry.getValue();
|
||
if (player.score.round_score * times < 0) {
|
||
if (player.hp.cur_hp + player.score.round_score * times < 0) {
|
||
if (player.hp.cur_hp > 0) {
|
||
lostAllJetton += Math.abs(player.hp.cur_hp);
|
||
}
|
||
} else {
|
||
lostAllJetton += Math.abs(player.score.round_score * times);
|
||
}
|
||
} else if (player.score.round_score * times > 0) {
|
||
allWinJetton += Math.abs(player.score.round_score * times);
|
||
}
|
||
}
|
||
|
||
if (allWinJetton <= 0) {
|
||
return;
|
||
}
|
||
|
||
for (Entry<Integer, Player> entry : this.playerMapBySeat.entrySet()) {
|
||
Player player = entry.getValue();
|
||
if (player.score.round_score * times > 0) {
|
||
double real_score = (double) lostAllJetton * (double) player.score.round_score * times
|
||
/ (double) allWinJetton;
|
||
player.score.d_real_score = real_score - (double) player.score.round_score * times;
|
||
} else if (player.score.round_score * times < 0
|
||
&& player.hp.cur_hp + player.score.round_score * times < 0) {
|
||
player.score.negative_score = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
public void clearHp() {
|
||
for (Entry<Integer, Player> entry : this.playerMapBySeat.entrySet()) {
|
||
Player player = entry.getValue();
|
||
player.clearHp();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 是否托管房间
|
||
*/
|
||
public boolean isEntrust() {
|
||
return this.openEntrust && this.isEntrust;
|
||
}
|
||
|
||
/**
|
||
* 托管是否结算
|
||
*/
|
||
public boolean entrustTotal() {
|
||
boolean entrustTotal = false;
|
||
if (this.isEntrust()) {
|
||
for (Entry<Integer, Player> entry : this.playerMapById.entrySet()) {
|
||
Player player = entry.getValue();
|
||
if (player.isEntrust() && player.manualAutoCard == false) {
|
||
if (this.entrusResultType == Constant.ENTRUST_CURREN_RESULT) {
|
||
entrustTotal = true;
|
||
} else if (this.entrusResultType == Constant.ENTRUST_TWO_RESULT) {
|
||
if (++player.entrust_round == 2) {
|
||
entrustTotal = true;
|
||
}
|
||
} else if (this.entrusResultType == Constant.ENTRUST_THREE_RESULT) {
|
||
if (++player.entrust_round == 3) {
|
||
entrustTotal = true;
|
||
}
|
||
} else if (this.entrusResultType == Constant.ENTRUST_TOTAL_RESULT1) {
|
||
if (++player.entrust_round == maxRound) {
|
||
entrustTotal = true;
|
||
}
|
||
}
|
||
if (entrustTotal) {
|
||
this.endType = Constant.END_TYPE_ENTRUST;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return entrustTotal;
|
||
}
|
||
|
||
public void notifyXiPai() {
|
||
ITObject param1 = new TObject();
|
||
ITArray list = TArray.newInstance();
|
||
for (Entry<Integer, Player> entry : this.playerMapById.entrySet()) {
|
||
Player player = (Player) entry.getValue();
|
||
if (player.xi_pai) {
|
||
list.addInt(player.playerid);
|
||
}
|
||
}
|
||
param1.putTArray("list", list);
|
||
broadCastToClient(0, Router.GAME_EVENT_NOTIFY_XIPAI, param1);
|
||
}
|
||
}
|