开头
以前开发的游戏活动,在普通的游戏活动上添加了跨服玩法,需要用到世界服务器中转,提供思路给大家参考
功能
简单介绍就是以帮会为组织的攻城类玩法,首先对服务器进行分组,每组的服务器玩家共同开采矿产,互相争夺矿产主权
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 : allGroupI