最近时间比较多的情况下,抱着对Realm Defense游戏的热爱,也由于在群内(帝国守卫战 Realm Defense 725166239)“康子”的英雄觉醒进度自动计算表的灵感下,信息生出了写一个网页版的Realm Defense英雄觉醒进度更新表,当然也要有一些其他的功能,这些功能会单独写一篇博客以供记录。
在今天,这个项目第一版已经跑起来了(如下图),由于是出版,很多细枝末节的东西并未做太多修改,页面使用了之前的一套后台框架。下面我将就这些功能使用的核心代码进行一些记录,也正好巩固自己的java开发能力。
代码项目结果如下图:
功能一:邮件通知功能,在每天模仿“打完境界钥匙后”,会自动更新英雄觉醒进度,然后通过邮件提醒用户。功能非常简单,代码也异常简单,就不过多阐述。
PS:参考SpringBoot邮件发送
功能二:mongodb实现自增主键id,一个非常实用的功能。
PS:参考 MongoDB进阶(九)Java中实现MongoDB自增主键ID
功能三:一些常用的POJO,像ResultMap和Status是用于给前端ajax之类的服务返回数据的一个返回结果的封装的统一。
PS:参考JavaLib | Result让你的API接口统一化(2)
功能四:模仿每天打境界碎片的过程,实用Springboot的定时任务,网上也有很多blog,不过多阐述,除了定时任务,其内的代码也是一些业务逻辑的相关代码。
PS:参考玩转SpringBoot之定时任务详解 在线Cron表达式生成器
功能五:文件读入英雄资料,由于英雄资料挺多,自已写了一个英雄资料的文档方便一次读入并添加进数据库。
PS:参考java读取文件和写入文件的方式 java文件读写操作指定编码格式 Java:利用I/O流读取文件内容
功能六:各种前端框架,讲真,一开始真地挺讨厌自己撸前端代码,但是自己无聊写自己感兴趣的项目时还是要自己撸啊!!!于是,唉。情势所迫啊,只好使用一些成熟的框架,自己开发一些还能看的页面吧。
PS:参考链接太多了,就不一一放了,每一个框架相关的使用都有很多博客提到,而且官方的文档也都很详细,特别表扬bootstrap和echart的官方文档。
PS:PS:还是放一些比较优秀的参考链接吧:Css效果之好看的边框颜色大全 bootstrap元素居中 前端渲染模板(一):Thymeleaf
功能七:基于游戏所需的业务功能代码,包括了英雄基本信息,英雄祝福时间记录,英雄觉醒进度记录,个人英雄觉醒规划等。由于最近特别喜欢MongoDB,于是所有数据全部存储到MongoDB里面了,哈哈,也是因为懒。这里着重贴一下HeroDao的代码,里面注解就是解释,关于mongoTemplate的使用网上也有很多资料,官方文档也写得不错。HeroDao里面主要是聚合和关联操作的代码比较重要,其他都是一些基本的查询。
PS:参考:MongoTemplate聚合操作MongoDB 使用mongoTemplate进行Aggregation聚合查询 MongoTemplate 聚合操作 mongodb 3.x 之实用新功能窥看[2] ——使用$lookup做多表关联处理 通过Aggregate $lookup操作 进行MongoDB的联表查询 Spring Data Mongodb多表关联查询
package com.aixh.realmdefense.realmDefense.dao;
import com.aixh.realmdefense.publicPojo.TatterAbout;
import com.aixh.realmdefense.realmDefense.pojo.AwakeningPlanning;
import com.aixh.realmdefense.realmDefense.pojo.Hero;
import com.aixh.realmdefense.realmDefense.pojo.HeroAwakeningProgress;
import com.aixh.realmdefense.realmDefense.pojo.WeeklyBlessedHero;
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import java.time.LocalDate;
import java.util.*;
/**
* @author myvina@qq.com
* @date 2019/3/7 0007 16:22
* @usage
*/
@Component
public class HeroDao {
private static final Logger logger = LoggerFactory.getLogger(HeroDao.class);
@Autowired
private MongoTemplate mongoTemplate;
public boolean saveObject(Object object) {
return mongoTemplate.save(object) == null;
}
public Hero getHeroByName(String name) {
Hero hero = null;
Query query = new Query(Criteria.where("name").is(name));
try {
hero = mongoTemplate.findOne(query, Hero.class);
} catch (Exception e) {
logger.error(e.toString());
e.printStackTrace();
}
return hero;
}
public List<Hero> getAllHero() {
List<Hero> heroes = null;
Query query = new Query();
query.with(new Sort(Sort.Direction.ASC, "incId"));
try {
heroes = mongoTemplate.find(query, Hero.class);
} catch (Exception e) {
logger.error(e.toString());
e.printStackTrace();
}
return heroes;
}
public Hero updateHeroByName(Hero hero) {
Query query = new Query(where("name").is(hero.getName()));
Update update = new Update()
.set("price", hero.getPrice())
.set("initialRank", hero.getInitialRank())
.set("highestRank", hero.getHighestRank())
.set("skills", hero.getSkills())
.set("talents", hero.getTalents());
FindAndModifyOptions options = new FindAndModifyOptions()
.upsert(true)
.returnNew(true);
Hero newHero = null;
try {
newHero = mongoTemplate.findAndModify(query, update, options, Hero.class);
} catch (Exception e) {
logger.error(e.toString());
e.printStackTrace();
}
return newHero;
}
/**
* 通过英雄名和赛季来过滤获得祝福英雄列表
* @param name 为空则搜索所有英雄
* @param session 为0则代表所有赛季
* @return
*/
public List<WeeklyBlessedHero> getBlessedHeroByNameAndSession(String name, int session, int offset, int limit) {
List<WeeklyBlessedHero> heroes = null;
Query query = new Query();
if(name != null && !name.equals(""))
query.addCriteria(Criteria.where("name").is(name));
if(session != 0)
query.addCriteria(Criteria.where("session").is(session));
if(offset >= 0 && limit > 0 ) {
query.skip(offset);
query.limit(limit);
}
query.with(new Sort(Sort.Direction.DESC, "session"));
query.with(new Sort(Sort.Direction.DESC, "date"));
try {
heroes = mongoTemplate.find(query, WeeklyBlessedHero.class);
} catch (Exception e) {
logger.error(e.toString());
e.printStackTrace();
}
return heroes;
}
public long getBlessedHeroCountByNameAndSession(String name, int session) {
long count = 0;
Query query = new Query();
if(name != null && !name.equals(""))
query.addCriteria(Criteria.where("name").is(name));
if(session != 0)
query.addCriteria(Criteria.where("session").is(session));
try {
count = mongoTemplate.count(query, WeeklyBlessedHero.class);
} catch (Exception e) {
logger.error(e.toString());
e.printStackTrace();
}
return count;
}
public List<Integer> getDistinctHeroRank(String userName) {
List<Integer> ranks = null;
try {
ranks = mongoTemplate.findDistinct(new Query(where("userName").is(userName)), "currentRank", HeroAwakeningProgress.class, Integer.class);
} catch (Exception e) {
logger.error(e.toString());
e.printStackTrace();
}
return ranks;
}
public List<String> getUnawakenedHeroNameByUserName(String userName) {
List<String> nameList = null;
LookupOperation lookupOperation = LookupOperation.newLookup().from("hero").localField("heroName").foreignField("name").as("isAwakeningCompleted");
AggregationOperation match = Aggregation.match(where("userName").is(userName));
TypedAggregation aggregation = Aggregation.newAggregation(HeroAwakeningProgress.class, lookupOperation, match);
try {
AggregationResults<Document> aggregationResults = mongoTemplate.aggregate(aggregation, Document.class);
nameList = new ArrayList<>();
List<Document> documents = aggregationResults.getMappedResults();
for(int i = 0; i < documents.size(); ++i) {
Document document = documents.get(i);
if(document.containsKey("currentRank")
&& document.containsKey("heroName")
&& document.containsKey("isAwakeningCompleted")) {
Document isAwakeningCompleted = (Document) ((List) document.get("isAwakeningCompleted")).get(0);
if(isAwakeningCompleted.containsKey("highestRank")
&& (Integer) document.get("currentRank") < (Integer) isAwakeningCompleted.get("highestRank")
&& document.containsKey("awakeningTatterNumber")
&& (Integer) document.get("awakeningTatterNumber") != TatterAbout.rankMaxTatterNumber[(Integer) document.get("currentRank")]) {
nameList.add(document.getString("heroName"));
}
}
}
} catch (Exception e) {
logger.error(e.toString());
e.printStackTrace();
}
return nameList;
}
public Long getHeroAwakeningProgressCountByNameAndRank(String userName, String heroName, int rank) {
Long count = 0L;
Query query = new Query(where("userName").is(userName));
if(heroName != null && !heroName.equals(""))
query.addCriteria(where("heroName").is(heroName));
if(rank != -1)
query.addCriteria(where("currentRank").is(rank));
try {
count = mongoTemplate.count(query, HeroAwakeningProgress.class);
} catch (Exception e) {
logger.error(e.toString());
e.printStackTrace();
}
return count;
}
public List<HeroAwakeningProgress> getHeroAwakeningProgressTableByNameAndRank(String userName, String heroName, int rank, int offset, int limit) {
List<HeroAwakeningProgress> list = null;
Query query = new Query(where("userName").is(userName));
if(heroName != null && !heroName.equals(""))
query.addCriteria(where("heroName").is(heroName));
if(rank != -1)
query.addCriteria(where("currentRank").is(rank));
if(offset >= 0 && limit > 0 ) {
query.skip(offset);
query.limit(limit);
}
try {
list = mongoTemplate.find(query, HeroAwakeningProgress.class);
} catch (Exception e) {
logger.error(e.toString());
e.printStackTrace();
}
return list;
}
public AwakeningPlanning getAwakeningPlanningByUserName(String userName) {
AwakeningPlanning awakeningPlanning = null;
Query query = new Query(where("userName").is(userName));
try {
awakeningPlanning = mongoTemplate.findOne(query, AwakeningPlanning.class);
} catch (Exception e) {
logger.error(e.toString());
e.printStackTrace();
}
return awakeningPlanning;
}
public AwakeningPlanning updateAwakeningPlanningByUserName(AwakeningPlanning awakeningPlanning) {
Query query = new Query(where("userName").is(awakeningPlanning.getUserName()));
Update update = new Update()
.set("dailyRealmNumber", awakeningPlanning.getDailyRealmNumber())
.set("heroAwakeningOrder", awakeningPlanning.getHeroAwakeningOrder())
.set("remainingKeysNumber", awakeningPlanning.getRemainingKeysNumber());
FindAndModifyOptions options = new FindAndModifyOptions()
.upsert(true)
.returnNew(true);
AwakeningPlanning newAwakeningPlanning = null;
try {
newAwakeningPlanning = mongoTemplate.findAndModify(query, update, options, AwakeningPlanning.class);
} catch (Exception e) {
logger.error(e.toString());
e.printStackTrace();
}
return newAwakeningPlanning;
}
public HeroAwakeningProgress getHeroAwakeningProgressByName(String userName, String heroName) {
HeroAwakeningProgress hap = null;
Query query = new Query(where("userName").is(userName));
query.addCriteria(where("heroName").is(heroName));
try {
hap = mongoTemplate.findOne(query, HeroAwakeningProgress.class);
} catch (Exception e) {
logger.error(e.toString());
e.printStackTrace();
}
return hap;
}
public HeroAwakeningProgress updateHeroAwakeningProgressByName(HeroAwakeningProgress hap) {
HeroAwakeningProgress heroAwakeningProgress = null;
Query query = new Query(where("userName").is(hap.getUserName()));
query.addCriteria(where("heroName").is(hap.getHeroName()));
Update update = new Update();
update.set("currentRank", hap.getCurrentRank());
update.set("awakeningTatterNumber", hap.getAwakeningTatterNumber());
FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions().returnNew(true).upsert(true);
try {
heroAwakeningProgress = mongoTemplate.findAndModify(query, update, findAndModifyOptions, HeroAwakeningProgress.class);
} catch (Exception e) {
logger.error(e.toString());
e.printStackTrace();
}
return heroAwakeningProgress;
}
static class SeasonStart {
public Integer _id;
public LocalDate start;
}
/**
* 获取赛季的开始时间
* @param session 为0则代表所有赛季
* @return
*/
public Map<Integer, LocalDate> getSeasonStart(int session) {
Map<Integer, LocalDate> map = null;
try {
map = new HashMap<>();
if(session == 0) {
Aggregation aggregation = Aggregation.newAggregation(Aggregation.group("session").min("date").as("start"));
AggregationResults<SeasonStart> results = mongoTemplate.aggregate(aggregation, "weeklyBlessedHero", SeasonStart.class);
List<SeasonStart> list = results.getMappedResults();
if(list != null) {
for(int i = 0; i < list.size(); ++i) {
map.put(list.get(i)._id, list.get(i).start);
}
}
return map;
}
Query query = new Query(where("session").is(session));
query.limit(1);
query.with(new Sort(Sort.Direction.ASC, "date"));
WeeklyBlessedHero hero = mongoTemplate.findOne(query, WeeklyBlessedHero.class);
if(hero != null)
map.put(hero.getSession(), hero.getDate());
return map;
} catch (Exception e) {
logger.error(e.toString());
e.printStackTrace();
}
return map;
}
public List<Integer> getDistinctSeason() {
List<Integer> seasons = null;
try {
seasons = mongoTemplate.findDistinct(new Query(), "session", WeeklyBlessedHero.class, Integer.class);
} catch (Exception e) {
logger.error(e.toString());
e.printStackTrace();
}
return seasons;
}
}
以上就是为rd这个游戏写的一个网页的第一版,功能比较简陋,也只能记录自己的英雄觉醒进度。以后会将很多功能补上。
中间断断续续有很长时间没有写。唉,一言难尽。努力码代码吧,加油!