ThousandDrawLogic.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. package com.ljsd.jieling.logic.thousandDraw;
  2. import com.ljsd.jieling.core.HandlerLogicThread;
  3. import com.ljsd.jieling.exception.ErrorCode;
  4. import com.ljsd.jieling.exception.ErrorCodeException;
  5. import com.ljsd.jieling.globals.BIReason;
  6. import com.ljsd.jieling.logic.dao.PlayerManager;
  7. import com.ljsd.jieling.logic.dao.ThousandDrawInfo;
  8. import com.ljsd.jieling.logic.dao.UserManager;
  9. import com.ljsd.jieling.logic.dao.root.User;
  10. import com.ljsd.jieling.network.session.ISession;
  11. import com.ljsd.jieling.protocols.CommonProto;
  12. import com.ljsd.jieling.protocols.MessageTypeProto;
  13. import com.ljsd.jieling.protocols.PlayerInfoProto;
  14. import com.ljsd.jieling.util.ItemUtil;
  15. import com.ljsd.jieling.util.MessageUtil;
  16. import config.SGlobalSystemConfig;
  17. import config.SLotteryRewardConfig;
  18. import config.SLotterySetting;
  19. import config.SThousandDrawConfig;
  20. import manager.STableManager;
  21. import org.slf4j.Logger;
  22. import org.slf4j.LoggerFactory;
  23. import util.MathUtils;
  24. import java.util.*;
  25. public class ThousandDrawLogic {
  26. private final int PER_GROUP_KEY_CARD_MAX = 1; //每组关键卡的数量
  27. private final int PER_GROUP_PURPLE_CARD_MAX = 1;//每组紫卡的数量
  28. private final int PER_GROUP_NORMAL_CARD_MAX = 8;//每组通用卡的数量
  29. private final int KEY_CARD = 1;
  30. private final int PURPLE_CARD = 2;
  31. private final int NORMAL_CARD = 3;
  32. private static final Logger LOGGER = LoggerFactory.getLogger(ThousandDrawLogic.class);
  33. private ThousandDrawLogic(){}
  34. private static class InnerClass {
  35. private static final ThousandDrawLogic instance = new ThousandDrawLogic();
  36. }
  37. public static ThousandDrawLogic getInstance(){
  38. return InnerClass.instance;
  39. }
  40. public boolean checkOpen(int uid) throws Exception {
  41. SGlobalSystemConfig sGlobalSystemConfig = STableManager.getConfig(SGlobalSystemConfig.class).get(1500);
  42. return HandlerLogicThread.checkOpen(UserManager.getUser(uid),sGlobalSystemConfig);
  43. }
  44. public void getThousandDrawInfo(ISession session) throws Exception {
  45. User user = UserManager.getUser(session.getUid());
  46. if(!checkOpen(user.getId())){
  47. throw new ErrorCodeException(ErrorCode.ACTIVITY_NOT_OPEN);
  48. }
  49. PlayerManager playerManager = user.getPlayerInfoManager();
  50. ThousandDrawInfo thousandDrawInfo = playerManager.getThousandDrawInfo();
  51. if(thousandDrawInfo == null){
  52. thousandDrawInfo = new ThousandDrawInfo();
  53. thousandDrawInfo.setRound(1);
  54. thousandDrawInfo.setCanTake(true);
  55. playerManager.setThousandDrawInfo(thousandDrawInfo);
  56. }
  57. List<PlayerInfoProto.ThousandDrawCard> list = new ArrayList<>();
  58. for(Map.Entry<Integer,List<Integer>> entry : thousandDrawInfo.getCards().entrySet()){
  59. PlayerInfoProto.ThousandDrawCard build = PlayerInfoProto.ThousandDrawCard.newBuilder()
  60. .setNumber(entry.getKey()).addAllCards(entry.getValue()).build();
  61. list.add(build);
  62. }
  63. LOGGER.info("getThousandDrawInfo uid:{},round:{},thousandDrawInfo.getCanTake():{}",user.getId(),thousandDrawInfo.getRound(),thousandDrawInfo.getCanTake());
  64. PlayerInfoProto.ThousandDrawInfoResponse build = PlayerInfoProto.ThousandDrawInfoResponse.newBuilder()
  65. .setRound(thousandDrawInfo.getRound()).addAllThousandDrawCards(list).setCanTake(thousandDrawInfo.getCanTake()).build();
  66. MessageUtil.sendMessage(session, 1, MessageTypeProto.MessageType.ThousandDrawInfoResponse.getNumber(), build, true);
  67. }
  68. /**
  69. * 抽卡
  70. */
  71. public void drawCard(ISession session, int number) throws Exception {
  72. User user = UserManager.getUser(session.getUid());
  73. if(!checkOpen(user.getId())){
  74. throw new ErrorCodeException(ErrorCode.ACTIVITY_NOT_OPEN);
  75. }
  76. PlayerManager playerManager = user.getPlayerInfoManager();
  77. ThousandDrawInfo thousandDrawInfo = playerManager.getThousandDrawInfo();
  78. if(thousandDrawInfo == null){
  79. LOGGER.error("drawCard uid:{},number:{}, thousandDrawInfo is null.",user.getId(),number);
  80. throw new ErrorCodeException(ErrorCode.PARAM_ERR);
  81. }
  82. int round = thousandDrawInfo.getRound();
  83. SThousandDrawConfig thousandDrawConfig = SThousandDrawConfig.getConfigByRound(round);
  84. if(thousandDrawConfig == null){
  85. LOGGER.error("drawCard uid:{},round:{}, thousandDrawConfig is null.",user.getId(),round);
  86. throw new ErrorCodeException(ErrorCode.CFG_NULL);
  87. }
  88. if(thousandDrawInfo.getCards().containsKey(number)){
  89. LOGGER.error("drawCard uid:{},round:{},number:{} .",user.getId(),round,number);
  90. throw new ErrorCodeException(ErrorCode.ALREADY_EXTRACT);
  91. }
  92. //key card
  93. List<Integer> keyCards = drawCardByType(user,thousandDrawConfig,KEY_CARD,number);
  94. //紫卡
  95. List<Integer> purpleCards = drawCardByType(user,thousandDrawConfig,PURPLE_CARD,number);
  96. //通用卡
  97. List<Integer> normalCards = drawCardByType(user,thousandDrawConfig,NORMAL_CARD,number);
  98. List<Integer> cardList = new ArrayList<>(keyCards);
  99. cardList.addAll(purpleCards);
  100. Collections.shuffle(normalCards);
  101. cardList.addAll(normalCards);
  102. playerManager.addThousandDrawCard(number,cardList);
  103. PlayerInfoProto.ThousandDrawCard build = PlayerInfoProto.ThousandDrawCard.newBuilder()
  104. .setNumber(number).addAllCards(thousandDrawInfo.getCards().get(number)).build();
  105. MessageUtil.sendMessage(session, 1, MessageTypeProto.MessageType.ThousandDrawResponse.getNumber(), build, true);
  106. }
  107. private List<Integer> drawCardByType(User user, SThousandDrawConfig thousandDrawConfig, int type, int number) throws Exception {
  108. int lotterySettingId = lotterySettingIdByTypeNumber(thousandDrawConfig,type,number);
  109. int round = thousandDrawConfig.getRound();
  110. SLotterySetting sLotterySetting = STableManager.getConfig(SLotterySetting.class).get(lotterySettingId);
  111. if(sLotterySetting == null) {
  112. LOGGER.error("drawCardByType uid:{},round:{},number:{},lotterySettingId:{}, sLotterySetting is null.",user.getId(),round,number,lotterySettingId);
  113. throw new ErrorCodeException(ErrorCode.CFG_NULL);
  114. }
  115. int perGroupMaxCard = getPerGroupMaxCardByType(type);
  116. List<Integer> cards = new ArrayList<>();
  117. for(int i = 0; i < perGroupMaxCard; i++){
  118. if(cards.size() >= perGroupMaxCard) continue;
  119. int rewardId = randomOne(user, sLotterySetting);
  120. SLotteryRewardConfig config = STableManager.getConfig(SLotteryRewardConfig.class).get(rewardId);
  121. int cardId = config.getReward()[0], cardNum = config.getReward()[1];
  122. if(cardNum > 1){
  123. for(int n = 0; n < cardNum; n++) {
  124. if(cards.size() >= perGroupMaxCard) continue;
  125. cards.add(cardId);
  126. }
  127. } else {
  128. cards.add(cardId);
  129. }
  130. }
  131. return cards;
  132. }
  133. private int lotterySettingIdByTypeNumber(SThousandDrawConfig config, int type, int number){
  134. switch (type){
  135. case KEY_CARD:
  136. {
  137. switch (number){
  138. case 1: return config.getSpecialLotteryID1();
  139. case 2: return config.getSpecialLotteryID2();
  140. case 3: return config.getSpecialLotteryID3();
  141. default: return -1;
  142. }
  143. }
  144. case PURPLE_CARD:{
  145. switch (number){
  146. case 1: return config.getPurpleLotteryID1();
  147. case 2: return config.getPurpleLotteryID2();
  148. case 3: return config.getPurpleLotteryID3();
  149. default: return -1;
  150. }
  151. }
  152. case NORMAL_CARD: return config.getCurrentLotteryID();
  153. default: return -1;
  154. }
  155. }
  156. private int getPerGroupMaxCardByType(int type){
  157. switch (type){
  158. case KEY_CARD: return PER_GROUP_KEY_CARD_MAX;
  159. case PURPLE_CARD: return PER_GROUP_PURPLE_CARD_MAX;
  160. case NORMAL_CARD: return PER_GROUP_NORMAL_CARD_MAX;
  161. default: return 0;
  162. }
  163. }
  164. private int randomOne(User user, SLotterySetting sLotterySetting) throws Exception {
  165. int pooId = getPooId(sLotterySetting);
  166. SLotteryRewardConfig sLotteryRewardConfig = randomHeroByPoolId(pooId, user);
  167. return sLotteryRewardConfig.getId();
  168. }
  169. private static int getPooId(SLotterySetting sLotterySetting) throws Exception {
  170. int[][] diamondBoxContain = sLotterySetting.getDiamondBoxContain();
  171. int totalWeight = 0;
  172. for (int i = 0; i < diamondBoxContain.length; i++) {
  173. int[] poolWeightInfo = diamondBoxContain[i];
  174. totalWeight += poolWeightInfo[1];
  175. }
  176. int randWeight = MathUtils.randomInt(totalWeight) + 1;
  177. int weight = 0;
  178. for (int i = 0; i < diamondBoxContain.length; i++) {
  179. int[] poolWeightInfo = diamondBoxContain[i];
  180. weight += poolWeightInfo[1];
  181. if (randWeight <= weight) {
  182. return poolWeightInfo[0];
  183. }
  184. }
  185. return 0;
  186. }
  187. private SLotteryRewardConfig randomHeroByPoolId(int poolId, User user) {
  188. List<SLotteryRewardConfig> sLotteryRewardConfigs = new ArrayList<>();
  189. List<SLotteryRewardConfig> sLotteryRewardConfigListByPoolId = SLotteryRewardConfig.getSLotteryRewardConfigListByPoolId(poolId);
  190. int totalCountByPoolId = 0;
  191. for (SLotteryRewardConfig sLotteryRewardConfig : sLotteryRewardConfigListByPoolId) {
  192. int[] openRules = sLotteryRewardConfig.getOpenRules();
  193. boolean canAdd = true;
  194. if (openRules != null && openRules.length > 0) {
  195. int openType = openRules[0];
  196. int openValue = openRules[1];
  197. switch (openType) {
  198. case 1:
  199. canAdd = user.getHeroManager().getRandomPoolInfo().getOrDefault(poolId, 0) > openValue;
  200. break;
  201. case 2:
  202. canAdd = user.getPlayerInfoManager().getLevel() > openValue;
  203. break;
  204. default: {
  205. break;
  206. }
  207. }
  208. }
  209. if (canAdd) {
  210. sLotteryRewardConfigs.add(sLotteryRewardConfig);
  211. totalCountByPoolId += sLotteryRewardConfig.getWeight();
  212. }
  213. }
  214. int randCount = MathUtils.randomInt(totalCountByPoolId) + 1;
  215. int weight = 0;
  216. for (SLotteryRewardConfig sLotteryRewardConfig : sLotteryRewardConfigs) {
  217. weight += sLotteryRewardConfig.getWeight();
  218. if (weight >= randCount) {
  219. return sLotteryRewardConfig;
  220. }
  221. }
  222. return null;
  223. }
  224. /**
  225. * 领取卡
  226. */
  227. public void takeCard(ISession session, int number) throws Exception {
  228. User user = UserManager.getUser(session.getUid());
  229. if(!checkOpen(user.getId())){
  230. throw new ErrorCodeException(ErrorCode.ACTIVITY_NOT_OPEN);
  231. }
  232. PlayerManager playerManager = user.getPlayerInfoManager();
  233. ThousandDrawInfo thousandDrawInfo = playerManager.getThousandDrawInfo();
  234. if(thousandDrawInfo == null){
  235. LOGGER.error("takeCard uid:{},number:{}, thousandDrawInfo is null.",user.getId(),number);
  236. throw new ErrorCodeException(ErrorCode.PARAM_ERR);
  237. }
  238. if (!thousandDrawInfo.getCanTake()) {
  239. LOGGER.error("takeCard uid:{},number:{}, can not take card.",user.getId(),number);
  240. throw new ErrorCodeException(ErrorCode.TOMORROW_TAKE_REWARD);
  241. }
  242. int round = thousandDrawInfo.getRound();
  243. SThousandDrawConfig thousandDrawConfig = SThousandDrawConfig.getConfigByRound(round);
  244. if(!thousandDrawInfo.getCards().containsKey(number)){
  245. LOGGER.error("takeCard uid:{},number:{}, thousandDrawInfo is null.",user.getId(),number);
  246. throw new ErrorCodeException(ErrorCode.PARAM_ERR);
  247. }
  248. if(thousandDrawConfig.getLvRequire() > user.getPlayerInfoManager().getLevel()){
  249. LOGGER.error("takeCard uid:{},number:{} player level not enough.",user.getId(),number);
  250. throw new ErrorCodeException(ErrorCode.PLAYER_LEVE_NOT);
  251. }
  252. for(int i = 1; i <= 3; i++){
  253. List<Integer> cardList = thousandDrawInfo.getCards().get(i);
  254. if(cardList == null || cardList.isEmpty()){
  255. LOGGER.error("takeCard uid:{},number:{}, cardList is null.",user.getId(),number);
  256. throw new ErrorCodeException(ErrorCode.PARAM_ERR);
  257. }
  258. }
  259. List<Integer> cardList = thousandDrawInfo.getCards().get(number);
  260. final int cardListSize = cardList.size();
  261. int hasHeroNum = user.getHeroManager().getHeroMap().size();
  262. if(hasHeroNum + cardListSize > user.getHeroManager().getHeroNumLimit()){
  263. throw new ErrorCodeException(ErrorCode.HERO_HERO_MAX);
  264. }
  265. int itemArr[][] = new int[cardListSize][];
  266. for(int i = 0; i < cardListSize; i++){
  267. itemArr[i]= new int[] {cardList.get(i),1};
  268. }
  269. CommonProto.Drop.Builder drop = ItemUtil.dropPer(user, itemArr, BIReason.THOUSAND_DRAW_REWARD);
  270. ThousandDrawInfo newInfo = new ThousandDrawInfo();
  271. newInfo.setRound(thousandDrawConfig.getNextRound());
  272. playerManager.setThousandDrawInfo(newInfo);
  273. PlayerInfoProto.ThousandDrawCard rewardBuild = PlayerInfoProto.ThousandDrawCard.newBuilder()
  274. .setNumber(number).setDrop(drop).build();
  275. MessageUtil.sendMessage(session, 1, MessageTypeProto.MessageType.ThousandDrawResponse.getNumber(), rewardBuild, true);
  276. }
  277. }