跨服夺矿战——java游戏服务器功能

跨服夺矿战——java游戏服务器功能

Scroll Down

开头
以前开发的游戏活动,在普通的游戏活动上添加了跨服玩法,需要用到世界服务器中转,提供思路给大家参考

功能
简单介绍就是以帮会为组织的攻城类玩法,首先对服务器进行分组,每组的服务器玩家共同开采矿产,互相争夺矿产主权

1、主要数据结构
public class MineGamer {
	/**
	 * 跨服国战分组id
	 */
	private int groupId;
	/**
	 * 区服标志
	 */
	private int serverType;
	/**
	 * 服务器ID
	 */
	private int serverId;
	/**
	 * 源服务器ID
	 */
	private int sourceId;
	/**
	 * 玩家ID
	 */
	private long gamerId;
	/**
	 * 工会ID
	 */
	private long armyId;
	/**
	 * 昵称
	 */
	private String nickName;
	/**
	 * 头像
	 */
	private String avatar;
	/**
	 * 战力
	 */
	private long power;
	/**
	 * 等级
	 */
	private int level;
玩家实体类,主要是服务器和展示信息。

public class WorldMineSimpleDto {
	/**
	 * 矿ID
	 */
	private int mineId;

	/**
	 * 矿区
	 */
	private int page;

	/**
	 * 矿类型
	 */
	private int type;
	/**
	 * 矿级别
	 */
	private int level;
	/**
	 * 天降宝箱状态
	 */
	private int boxActive;
	/**
	 * 天降宝箱id
	 */
	private int exboxId;
	/**
	 * 占领时间  小于10min为保护状态
	 */
	private long occupeTime;
	/**
	 * 预计占领结束时间
	 */
	private long occupeEndTime;
	/**
	 * 领取宝箱状态
	 */
	private List<Integer> boxReward;
	/**
	 * 玩家信息
	 */
	private MineGamer mineGamer;

矿产实体类,为矿产分区占领等信息,其余类怪物npc,活动状态及时间,玩家占领等信息都比较少。

2、活动管理
跨服功能的主要重心都在世界服,主要处理和保存活动信息
活动分组管理:初始读取夺矿战分组配置表

public class CrossMineGroupService extends ConfigServiceAdapter {
	private static Map<Integer, SeizeMineGroupServerConfig> CONFIG_MAPS = new HashMap<>();

	@Override
	public void clear() {
		CONFIG_MAPS.clear();
	}

	@Override
	public void initialize() {
		Collection<SeizeMineGroupServerConfig> list = dataConfig.listAll(this, SeizeMineGroupServerConfig.class);
		for (SeizeMineGroupServerConfig cfg : list) {
			CONFIG_MAPS.put(cfg.getId(), cfg);
		}
	}

	public static SeizeMineGroupServerConfig get(int id) {
		return CONFIG_MAPS.get(id);
	}

	public static SeizeMineGroupServerConfig get(int serverId, int serverType) {
		Collection<SeizeMineGroupServerConfig> groupServerConfigList = getCrossBattleGroupServerList();
		for (SeizeMineGroupServerConfig groupServerConfig : groupServerConfigList) {
			Set<ServerStruct> serverStructs = groupServerConfig.getServerStructs();
			for (ServerStruct serverStruct : serverStructs) {
				if (serverStruct.getServerId() == serverId && serverStruct.getServerType() == serverType) {
					return groupServerConfig;
				}
			}
		}
		return null;
	}

/**
 * 服务器简单结构
 * @author CharonWang
 *
 */
public class ServerStruct {
	/**
	 * 服务器类型
	 */
	private int serverType;
	/**
	 * 服务器ID
	 */
	private int serverId;

	public static ServerStruct valueOf(int serverType, int serverId) {
		ServerStruct model = new ServerStruct();
		model.serverType = serverType;
		model.serverId = serverId;
		return model;
	}

//矿产分组表
@DataFile(fileName = "seize_mine_groups_server_config")
public class SeizeMineGroupServerConfig implements ModelAdapter {
	/**
	 * 组ID
	 */
	private int id;
	/**
	 * 服务器列表
	 */
	private String servers;
	/**
	 * 组名称
	 */
	private String name;

	@FieldIgnore
	private Set<ServerStruct> serverStructs = new HashSet<>();

	@Override
	public void initialize() {
		List<String> serverList = JSONObject.parseArray(servers, String.class);
		for (String server : serverList) {
			String[] strArray = server.split("-");
			serverStructs.add(ServerStruct.valueOf(Integer.valueOf(strArray[0]), Integer.valueOf(strArray[1])));
		}
	}
活动时间管理

/**
 * 跨服夺矿战信息
 * @author aurora
 *
 */
public class MineEntity extends RedisEntity {
	
	/**
	 * 状态
	 */
	private int state;
	/**
	 * 状态结束时间
	 */
	private long stateEndTime;


根据配置的活动时间,定时器控制活动状态,具体方法代码如下,战斗功能不是写我的也比较长最后再贴,其余的就是基本的增删改查

@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		mineEntity = mineDao.get();
		if (mineEntity.getState() == 0) {
			mineEntity.setStateEndTime(System.currentTimeMillis());
			mineEntity.setState(MineState.PREPARE.getId());
			mineDao.update(mineEntity);
		}
		mineWorldDao.initMineWorld(mineEntity.getState());
		schedule.addEverySecond(new Runnable() {
			@Override
			public void run() {
				processMineState();
			}
		}, 5);
	}

// 跨服夺矿战战状态处理
	@SuppressWarnings("incomplete-switch")
	private void processMineState() {
		MineState state = MineState.getState(mineEntity.getState());
		if (state != MineState.PREPARE) {
			isfreshMine();
		}
		if (System.currentTimeMillis() < mineEntity.getStateEndTime()) {
			return;
		}
		switch (state) {
		case MESSPLAY:
			if (System.currentTimeMillis() < mineEntity.getStateEndTime()) {
				return;
			}
			// 发送宝箱倒计时
			processMineBox();
			// 更新时间,延长30min
			mineEntity.setStateEndTime(mineEntity.getStateEndTime() + 30 * 60 * 1000);
			mineEntity.setState(MineState.SENDREWARD.getId());
			mineDao.update(mineEntity);
			break;
		case SENDREWARD:
			if (System.currentTimeMillis() < mineEntity.getStateEndTime()) {
				return;
			}
			// 发送邮件宝箱
			sendMineBoxReward();
			// 更新发宝箱的时间
			mineEntity.setStateEndTime(getBoxTime());
			mineEntity.setState(WarState.MESSPLAY.getId());
			mineDao.update(mineEntity);
			break;
		case PREPARE:
			clean();
			initMine();
			// 初始化发宝箱时间
			mineEntity.setStateEndTime(getBoxTime());
			mineEntity.setState(MineState.MESSPLAY.getId());
			mineDao.update(mineEntity);
			break;
		}
	}
	private void isfreshMine() {
		Collection<Integer> allGroupIds = CrossMineGroupService.allGroupIds();
		for (Integer groupId : allGroupIds) {
			List<MineWorldPlayerEntity> mineList = mineWorldDao.getMineList(groupId);
			for (MineWorldPlayerEntity mineWorld : mineList) {
				if (mineWorld == null) {
					LOGGER.error("mineWorld can't find groupId:{}", groupId);
					continue;
				}
				// 判断是否为有主高级矿 占领时间已过
				if (mineWorld != null && mineWorld.getOccuperId() != 0) {
					if (System.currentTimeMillis() >= mineWorld.getOccupeEndTime()) {
						boolean settleReward = settleReward(mineWorld, 1);
						if (settleReward) {
							mineWorld.initi();
							mineWorldDao.update(mineWorld);
						}
					}
				}
			}
		}
	}

	private long getBoxTime() {
		long boxtime1 = TimeUtils.getTodayFixTime(12);
		long boxtime2 = TimeUtils.getTodayFixTime(21);
		long timeMillis = System.currentTimeMillis();
		if (timeMillis <= boxtime1) {
			timeMillis = boxtime1;
		} else if (timeMillis > boxtime1 && timeMillis <= boxtime2) {
			timeMillis = boxtime2;
		} else {
			// 设置为第二天12点
			timeMillis = boxtime1 + 24 * 60 * 60 * 1000;
		}
		return timeMillis;
	}

	// 跨服国夺矿战宝箱发送倒计时
	private void processMineBox() {
		Collection<Integer> allGroupIds = CrossMineGroupService.allGroupIds();
		for (Integer groupId : allGroupIds) {
			List<MineWorldPlayerEntity> mineList = mineWorldDao.getMineList(groupId);
			for (MineWorldPlayerEntity mineWorld : mineList) {
				if (mineWorld == null) {
					LOGGER.error("mineWorld can't find groupId:{}", groupId);
					continue;
				}
				SeizeMineConfig mineConfig = MineWorldService.getMineConfig(mineWorld.getMineId());
				// 判断是否为有主高级矿 是激活&& mineConfig.getMineType() == 2
				if (mineWorld.getOccuperId() != 0) {
					if (!mineConfig.getExBox().isEmpty() && mineConfig.getExBoxId() > 0) {
						mineWorld.setBoxActive(1);
						mineWorld.setExboxId(mineConfig.getExBoxId());
						mineWorldDao.update(mineWorld);
					}
				}
			}
		}
	}

	// 跨服国夺矿战宝箱处理
	private void sendMineBoxReward() {
		Collection<Integer> allGroupIds = CrossMineGroupService.allGroupIds();
		for (Integer groupId : allGroupIds) {
			List<MineWorldPlayerEntity> mineList = mineWorldDao.getMineList(groupId);
			for (MineWorldPlayerEntity mineWorld : mineList) {
				if (mineWorld == null) {
					LOGGER.error("mineWorld can't find groupId:{}", groupId);
					continue;
				}
				// 判断是否为已激活有主矿
				if (mineWorld.getBoxActive() == 1) {
					// 发放奖励
					int exboxId = mineWorld.getExboxId();
					mineWorld.setBoxActive(0);
					mineWorld.setExboxId(0);
					mineWorldDao.update(mineWorld);
					if (mineWorld.getOccuperId() != 0) {
						SeizeMineExboxConfig exboxConfig = MineExBoxConfigService.getMineConfig(exboxId);
						if (exboxConfig != null && exboxConfig.getRewards() != null) {
							sendExBoxReward(mineWorld, exboxConfig.getRewards());
						}
					}

				}
			}
		}
	}

	/**
	 * 初始化矿类
	 */
	private void initMine() {
		Collection<Integer> allGroupIds = CrossMineGroupService.allGroupIds();
		for (Integer groupId : allGroupIds) {
			Set<Integer> mineIds = MineWorldService.getMineId();
			for (Integer mineId : mineIds) {
				MineWorldPlayerEntity mineEntiy = MineWorldPlayerEntity.valueof(groupId, mineId, MineWorldService.getMineConfig(mineId).getPage(),
						MineWorldService.getBattleMonster(mineId));
				mineWorldDao.update(mineEntiy);
			}
		}
	}

	/**
	 * 清理夺矿战上期数据
	 */
	public void clean() {
		if (mineEntity.getState() != WarState.PREPARE.getId()) {
			return;
		}
		Collection<Integer> allGroupIds = CrossWarGroupServerService.allGroupIds();
		for (Integer groupId : allGroupIds) {
			mineWorldDao.cleanMine(groupId);
		}
		mineWorldDao.cleanMap();
	}

3、游戏功能
夺矿玩法分为游戏服和世界服,游戏服主要是储存玩家数据,和客户端对接协议,和世界服信息交互。
查询矿产一套流程代码

	/**
	 * 一键搜索剩余矿区信息   
	 * 
	 * @param object
	 * @return
	 */
	@RequestMapping(value = "/queryMineList", method = RequestMethod.POST)
	public @ResponseBody GaloshesJsonResultProtocol queryMineList(@RequestBody JSONObject object) {

		return handle(object, new HandlerResultCallBack<Object>() {
			@Override
			public Object call(Long gamerId, JSONObject object) throws Exception {
				MineTypeListDto queryMineList = mineFacade.queryMineList(gamerId);
				return queryMineList;
			}
		});
	}


    public MineTypeListDto queryMineList(Long gamerId) {
		JSONObject param = new JSONObject();
		param.put("gamerId", gamerId);
		MineTypeListDto queryDto = worldService.obtainTCrossBattle(param, "mine/queryMineList", MineTypeListDto.class);
		return queryDto;
	}

与世界服建立连接,后面的新项目使用了RPC协议会比现在舒服很多

@Component
public class WorldService implements GameInit {

	public final static String WORLD_CONTEXT_NAME = "domain-world";

	public final static String REGIST_URI = "system/regist";
	public final static String FORWARD_URI = "system/forward";

	public List<WorldRankInfo> pagodaRanks = Lists.newCopyOnWriteArrayList();

	private static final Logger LOGGER = LoggerFactory.getLogger(WorldService.class);
	@Autowired
	private IHttpClient httpClient;
	@Value("${server.worldUrl}")
	private String worldUrl;
	@Value("${server.worldEnable}")
	private boolean worldEnable = false;
	@Value("${server.flag}")
	public String serverType;
	@Autowired
	@Qualifier("serverId")
	public int serverId;
	@Value("${server.compose}")
	private String compose;

	public boolean registToWord() {
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("serverId", serverId);
		jsonObject.put("port", 30000 + serverId);
		jsonObject.put("serverType", serverType);
		jsonObject.put("composeIds", compose);
		try {
			String res = httpClient.sendPost(getPath(REGIST_URI), jsonObject.toJSONString(), "application/json");
			if (res == null) {
				return false;
			}
			JsonResultProtocol jsonResultProtocol = JSON.parseObject(res, JsonResultProtocol.class);
			if (jsonResultProtocol.getResult() == ResultCode.SUCCESS.getCode()) {
				return true;
			}
			return false;

		} catch (Exception e) {
			LOGGER.error("{}", e);
			return false;
		}
	}

	/**
	 * 从世界服获取消息
	 *
	 * @param jsonObject 数据
	 * @param path       绝对路径,以下划线开头
	 * @return
	 * @return
	 */
	public <T> T obtainTCrossBattle(JSONObject jsonObject, String path, Class<T> tClazz) {

		if (path == null || path.isEmpty()) {
			throw new RuntimeException("path is null!!!!!");
		}
		try {
			String fullUrl = getPath(path);
			jsonObject.put("serverId", serverId);
			jsonObject.put("serverType", serverType);
			String res = httpClient.sendPost(fullUrl, jsonObject.toJSONString(), "application/json");
			if (res == null) {
				throw new CrossBattleRemoteDataException();
			}
			JsonResultProtocol parseObject = JSON.parseObject(res, JsonResultProtocol.class);
			if (parseObject.getMessage() == null || "".equals(parseObject.getMessage())) {
				throw new CrossBattleRemoteDataException();
			}
			return JSON.parseObject(parseObject.getMessage().toString(), tClazz);

		} catch (Exception e) {
			LOGGER.error("{}", e);
			throw new CrossBattleRemoteDataException();
		}
	}
    
世界服用的redis数据库,主要保存矿产数据,处理玩家间的信息。

	/**
	 * 一键搜索剩余矿区信息
	 * 
	 * @param object
	 * @return
	 */
	@RequestMapping(value = "/queryMineList", method = RequestMethod.POST)
	@ResponseBody
	public JsonResultProtocol queryMineList(@RequestBody JSONObject object) {
		JsonResultProtocol jsonResultProtocol = new JsonResultProtocol();
		try {
			int serverType = object.getIntValue("serverType");
			int serverId = object.getIntValue("serverId");
			MineTypeListDto dto = mineFacade.queryMineList(serverId, serverType);
			jsonResultProtocol.setup(ResultCode.SUCCESS.getCode(), JSON.toJSONString(dto));
		} catch (Exception e) {
			LOGGER.error("{}", e);
			jsonResultProtocol.setup(ResultCode.SERVER_ERROR.getCode());
		}
		return jsonResultProtocol;
	}

/**
	 * 获取矿区矿产信息
	 */
	public MineTypeListDto queryMineList(int serverId, int serverType) {
		List<WorldMineSimpleDto> mineSimpleDtoList = Lists.newArrayList();
		int groupId = CrossMineGroupService.getGroupId(serverId, serverType);
		if (groupId <= 0) {
			LOGGER.error("CrossMine can't find groupId, serverId:{}, serverType:{}", serverId, serverType);
			return null;
		}
		List<MineWorldPlayerEntity> mineList = mineWorldDao.getMineList(groupId);
		// 记录剩余矿区信息
		for (MineWorldPlayerEntity mineWorldPlayerEntity : mineList) {
			if (mineWorldPlayerEntity.getOccuperId() != 0) {
				continue;
			}
			int idpage = mineWorldPlayerEntity.getPage();
			int mineId = mineWorldPlayerEntity.getMineId();
			SeizeMineConfig mineConfig = MineWorldService.getMineConfig(mineId);
			WorldMineSimpleDto mineSimple = WorldMineSimpleDto.valueOf(mineId, idpage, mineConfig.getMineType(), mineConfig.getMineLevel(),
					mineWorldPlayerEntity.getMineGamer());
			mineSimple.setOccupeTime(mineWorldPlayerEntity.getOccupeTime());
			mineSimple.setOccupeEndTime(mineWorldPlayerEntity.getOccupeEndTime());
			if (mineConfig.getMineType() == 2) {
				// 高级矿信息储存
				mineSimple.setBoxActive(mineWorldPlayerEntity.getBoxActive());
			}
			mineSimpleDtoList.add(mineSimple);
		}
		return MineTypeListDto.valueOf(mineSimpleDtoList);
	}

主要流程就是这样,当初做的比较匆忙,现在回想还是有很多可以优化的地方,也给大家写功能的时候参考

4.跨服战斗
获取矿产占领者的id进入战斗,击败对方则更新占领城池广播,如果对手是玩家,通知对手加入仇人信息

// 获取矿产信息
		MineWorldPlayerEntity mineWorldPlayerEntity = mineWorldDao.get(groupId, mineId);
		SeizeMineConfig mineConfig = MineWorldService.getMineConfig(mineId);
		// 判断是否已经占领过矿
		List<MineWorldPlayerEntity> mineList = mineWorldDao.getMineList(groupId);
		for (MineWorldPlayerEntity minePlayerEntity : mineList) {
			if (minePlayerEntity.getOccuperId() == gamerId) {
				SeizeMineConfig gamerMine = MineWorldService.getMineConfig(minePlayerEntity.getMineId());
				if (gamerMine.getMineType() == mineConfig.getMineType()) {
					return null;
				}
			}
		}
		long protectTime = globalService.load(GlobalConfigKey.SEIZEMINEPROTECTTIME).findInt() * TimeConstant.ONE_MINUTE_MILLISECOND;
		if (mineConfig.getMineLevel() == 1) {
			// 如果当前未过保护时间 低级矿保护
			if (mineWorldPlayerEntity.getOccupeTime() + protectTime >= System.currentTimeMillis()) {
				return null;
			}
		}
		List<BattleRole> opponentBattleRoleList = Lists.newArrayList();
		WorldMinePlayResultDto playResultDto;
		if (mineWorldPlayerEntity.getOccuperId() == 0) {
			// 对手怪物信息
			opponentBattleRoleList = MineWorldService.getBattleRole(mineId);
			LinkedList<BattleRole> opponentBattleRoles = Lists.newLinkedList();
			for (BattleRole battleRole : opponentBattleRoleList) {
				BattleRole copyBattleRole = new BattleRole(battleRole.getRoleId(), battleRole.getBelong(), battleRole.getVocation(),
						battleRole.getBattleAttr().copy(), battleRole.getTotalAttr().copy(), battleRole.getBattleSkillAttrs());
				opponentBattleRoles.add(copyBattleRole);
			}
			LinkedList<BattleRole> challengeBattleRoles = worldMinePlayDto.getChallengeBattleRoles();
			for (BattleRole battleRole : challengeBattleRoles) {
				battleRole.setTotalAttr(battleRole.getBattleAttr().copy());
			}
			BattleFight battleFight = new BattleFight(gamerId, mineId, challengeBattleRoles, opponentBattleRoles);
			BattleResult battleResult = battleMonitor.playBattle(battleFight, false, PlayType.NONE, null);
			playResultDto = WorldMinePlayResultDto.valueOf(battleResult, 1);
		} else {
			// 对手是玩家
			MineGamer mineGamersource = mineWorldPlayerEntity.getMineGamer();
			GamerBattleRoleDto battle = getBattle(mineGamersource.getServerType(), mineGamersource.getServerId(), mineGamersource.getGamerId());
			if (battle == null) {
				LOGGER.error("CrossMine can't getBattle Message, serverType:{}, serverId:{}", mineGamersource.getServerType(),
						mineGamersource.getServerId());
				return null;
			}
			LinkedList<BattleRole> challengeBattleRoles = worldMinePlayDto.getChallengeBattleRoles();
			for (BattleRole battleRole : challengeBattleRoles) {
				battleRole.setTotalAttr(battleRole.getBattleAttr().copy());
			}
			BattleFight battleFight = new BattleFight(gamerId, mineGamersource.getGamerId(), challengeBattleRoles, battle.getChallengeBattleRoles());
			BattleResult battleResult = battleMonitor.playBattle(battleFight, PlayType.NONE, null);
			playResultDto = WorldMinePlayResultDto.valueOf(battleResult, battle.getPoints(), 2);
			// 更新玩家仇人信息
			mineGamer.setGroupId(groupId);
			saveOppend(mineGamersource, mineGamer, battleResult, mineId);
		}
		// 玩家胜利更新数据
		if (playResultDto.getWinner() == gamerId) {
			// 被攻击玩家结算奖励
			if (mineWorldPlayerEntity.getOccuperId() != 0) {
				boolean settleReward = settleReward(mineWorldPlayerEntity, 3);
				if (!settleReward) {
					return null;
				}
				mineWorldPlayerEntity.initi();
			}
			// 初始矿产占领时长
			long initialTime = globalService.load(GlobalConfigKey.SeizeMineInitialTime).findInt() * TimeConstant.ONE_MINUTE_MILLISECOND;
			mineWorldPlayerEntity.setOccuperId(gamerId);
			mineWorldPlayerEntity.setOccupeTime(System.currentTimeMillis());
			mineWorldPlayerEntity.setOccupeEndTime(mineWorldPlayerEntity.getOccupeTime() + initialTime);
			mineWorldPlayerEntity.setMineGamer(mineGamer);
			mineWorldDao.update(mineWorldPlayerEntity);
			// 记录消息类
			MineWorldMessageEntity messageEntity = MineWorldMessageEntity.valueof(groupId, mineId, mineGamer);
			List<MineWorldMessageEntity> mineMessageList = mineWorldMessageDao.getMineMessageList(groupId);
			// 储存最多30条
			if (mineMessageList.size() >= 30) {
				mineMessageList.remove(0);
			}
			mineMessageList.add(messageEntity);
			mineWorldMessageDao.saveMineMessageList(groupId, mineMessageList);
		}
		return playResultDto;
	}
发送信息到被攻击者服务器

/**
	 * 
	 * @param mineGamer
	 *            被攻打者信息
	 * @param oppendMineGamer
	 *            攻打记录的仇敌
	 * @param battleResult
	 * @param mineId
	 * @return
	 */

	private boolean saveOppend(MineGamer mineGamer, MineGamer oppendMineGamer, BattleResult battleResult, int mineId) {
		int serverId = mineGamer.getServerId();
		int serverType = mineGamer.getServerType();
		Server server = serverDao.getServer(serverId, serverType);
		if (server == null) {
			LOGGER.error("serizeMina saveOppend server not found, serverType:{},serverId:{}", serverType, serverId);
			return false;
		}
		String url = "http://" + server.getHost() + ":" + server.getPort() + "/" + PathConstant.GAME_CONTEXT_NAME + PathConstant.WORLD_OPPONENT_MINE;
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("mineGamer", mineGamer);
		jsonObject.put("oppendMineGamer", oppendMineGamer);
		jsonObject.put("battleResult", battleResult);
		jsonObject.put("mineId", mineId);
		String result = innerHttpClient.sendPost(url, jsonObject.toJSONString(), "application/json");
		if (StringUtils.isEmpty(result)) {
			LOGGER.error("serizeMina saveOppend http error, url:{},jsonObject:{}", url, jsonObject.toJSONString());
			return false;
		}
		JsonResultProtocol jsonResultProtocol = JSON.parseObject(result, JsonResultProtocol.class);
		if (jsonResultProtocol.getResult() != ResultCode.SUCCESS.getCode()) {
			LOGGER.error("serizeMina saveOppend result error, url:{},jsonObject:{},result:{}", url, jsonObject.toJSONString(),
					JSONObject.toJSONString(jsonResultProtocol));
			return false;
		}
		boolean istrue = JSONObject.parseObject(jsonResultProtocol.getMessage().toString(), boolean.class);
		return istrue;

	}
战斗类

public class BattleMonitor {

	@Resource
	private FightMonitor fightMonitor;

	public BattleResult playBattle(BattleFight battleFight, boolean copyAttr, PlayType playType, Object object) {
		if (copyAttr) {
			copyAttr(battleFight);
		}
		return play(battleFight, playType, object);
	}

	private void copyAttr(BattleFight battleFight) {
		LinkedList<BattleRole> challengeRoleAttrs = battleFight.getChallengeRoleAttrs();
		for (BattleRole battleRole : challengeRoleAttrs) {
			battleRole.setTotalAttr(battleRole.getBattleAttr().copy());
		}
		LinkedList<BattleRole> opponentRoleAttrs = battleFight.getOpponentRoleAttrs();
		for (BattleRole battleRole : opponentRoleAttrs) {
			battleRole.setTotalAttr(battleRole.getBattleAttr().copy());
		}
	}

	private BattleResult play(BattleFight battleFight, PlayType playType, Object object) {
		BattleResult battleResult = new BattleResult();
		Iterator<BattleRole> challengeRoles = battleFight.getChallengeRoleAttrs().iterator();
		Iterator<BattleRole> defenceRoles = battleFight.getOpponentRoleAttrs().iterator();

		BattleRole challengeRole = challengeRoles.next();
		while (challengeRoles.hasNext() && !challengeRole.hasAlive()) {
			challengeRole = challengeRoles.next();
		}
		BattleRole defenceRole = defenceRoles.next();
		while (defenceRoles.hasNext() && !defenceRole.hasAlive()) {
			defenceRole = defenceRoles.next();
		}
		boolean challengeFirst = true;
		boolean defenceFirst = true;
		long winner = 0;
		long last = 0;
		long lastLeftHp = 0;
		List<Long> left = Lists.newArrayList();
		for (;;) {
			FightResult fightResult = fightMonitor.fight(challengeRole, defenceRole, challengeFirst, defenceFirst, playType, object);
			battleResult.addReports(fightResult.getReports());
			if (fightResult.hasWinnerWas(challengeRole.getRoleId())) {
				if (!defenceRoles.hasNext()) {
					winner = battleFight.getChallenge();
					last = challengeRole.getRoleId();
					lastLeftHp = challengeRole.getTotalAttr().getHp();
					break;
				}
				defenceRole = defenceRoles.next();
				defenceFirst = true;
				challengeFirst = false;
				challengeRole.cleanAccumulateSpeed();
			} else {
				if (!challengeRoles.hasNext()) {
					winner = battleFight.getOpponent();
					last = defenceRole.getRoleId();
					lastLeftHp = defenceRole.getTotalAttr().getHp();
					break;
				}
				challengeRole = challengeRoles.next();
				challengeFirst = true;
				defenceFirst = false;
				defenceRole.cleanAccumulateSpeed();
			}
		}
		//win
		if (winner == battleFight.getChallenge()) {
			left.add(challengeRole.getRoleId());
			while (challengeRoles.hasNext()) {
				left.add(challengeRoles.next().getRoleId());
			}
		} else {
			left.add(defenceRole.getRoleId());
			while (defenceRoles.hasNext()) {
				left.add(defenceRoles.next().getRoleId());
			}
		}
		battleResult.win(winner, last, lastLeftHp, left);
		return battleResult;
	}

	public BattleResult playBattle(BattleFight battleFight, PlayType playType, Object object) {
		return playBattle(battleFight, true, playType, object);
	}

}


@Component
public class FightMonitor {

	@Resource
	private BaseAttackAct baseAttackAct;

	@Resource
	private BaseSkillAct baseSkillAct;

	@Resource
	private EffectAct effectAct;

	/**
	 * 判断谁先出手
	 * @param challengeRole
	 * @param opponentRole
	 * @param challengeFirst
	 * @param defenceFirst
	 * @return
	 */
	private boolean hasChallengeRoleActFirst(BattleRole challengeRole, BattleRole opponentRole, boolean challengeFirst, boolean defenceFirst) {
		if (challengeFirst) {
			if (defenceFirst) {
				if (challengeRole.getBattleAttr().getSpeed() > opponentRole.getBattleAttr().getSpeed()) {
					return true;
				}
			} else {
				return true;
			}
		}
		return false;
	}

	public FightResult fight(BattleRole challengeRole, BattleRole opponentRole, boolean challengeFirst, boolean defenceFirst, PlayType playType,
			Object object) {
		long winner = 0;
		List<RoundReport> reports = Lists.newArrayList();
		boolean firstAttack = hasChallengeRoleActFirst(challengeRole, opponentRole, challengeFirst, defenceFirst);
		BattleRole attackRole = null;
		BattleRole defenceRole = null;
		if (firstAttack) {
			attackRole = challengeRole;
			defenceRole = opponentRole;
		} else {
			defenceRole = challengeRole;
			attackRole = opponentRole;
			boolean challengeTemp = challengeFirst;
			challengeFirst = defenceFirst;
			defenceFirst = challengeTemp;
		}
		int attackRound = 1;
		int defenceRound = 1;
		for (;;) {
			if (!attackRole.hasAlive()) {
				winner = attackRole.getRoleId();
				break;
			}
			RoundReport roundReport = roundAttack(attackRole, defenceRole, challengeFirst, defenceFirst, attackRound, defenceRound, playType, object);
			challengeFirst = false;
			defenceFirst = false;
			reports.add(roundReport);
			if (!defenceRole.hasAlive()) {
				winner = attackRole.getRoleId();
				break;
			}
			if (!attackRole.hasAlive()) {
				winner = defenceRole.getRoleId();
				break;
			}
			BattleRole tempRole = attackRole;
			attackRole = defenceRole;
			defenceRole = tempRole;
			attackRound++;
			int tempRound = attackRound;
			attackRound = defenceRound;
			defenceRound = tempRound;
		}

		return new FightResult(winner, reports);
	}

	private RoundReport roundAttack(BattleRole attackRole, BattleRole defenceRole, boolean challengeFirst, boolean defenceFirst, int attackRound,
			int defenceRound, PlayType playType, Object object) {
		RoundReport roundReport = new RoundReport(attackRole.getRoleId(), attackRole.getBelong(), defenceRole.getRoleId());

		List<ActResult> bufferActs = effectAct.processEffect(attackRole);
		if (bufferActs.size() > 0) {
			roundReport.addActResults(bufferActs);
		}
		for (BattleSkillAttr battleSkillAttr : attackRole.getBattleSkillAttrs()) {
			//在battleSkillAttr中增加一个方法 用来使技率生效影响基本技能触发几率
			if (battleSkillAttr.canTriggerSkill(attackRound, attackRole.getTotalAttr().getSkillChance())) {

				ActResult result = baseSkillAct.act(battleSkillAttr, attackRole, defenceRole, challengeFirst, attackRound);
				roundReport.addActResult(result);
				break;
			}
		}
		// 判断战斗回合大于100,被攻击着输
		if (attackRound > 100) {
			if (defenceRole.getBattleAttr().getHp() > attackRole.getBattleAttr().getHp()) {
				attackRole.getBattleAttr().setHp(0);
			} else {
				defenceRole.getBattleAttr().setHp(0);
			}
		}
		List<ActResult> act = baseAttackAct.act(attackRole, defenceRole, challengeFirst, defenceFirst, playType, object);
		roundReport.addActResults(act);

		return roundReport;
	}
}

差不多就是这些,现在是用lua语言写起来简单很多,新接的战令功能根据开始时间和活动持续时间自行运转,看看夺矿战状态流程管理复习下,现在记性不行,要把以前学的都慢慢记录下来了