Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >服务端模块:周期性次数重置

服务端模块:周期性次数重置

作者头像
香菜聊游戏
发布于 2021-06-07 07:47:11
发布于 2021-06-07 07:47:11
69300
代码可运行
举报
文章被收录于专栏:香菜聊游戏香菜聊游戏
运行总次数:0
代码可运行

游戏开发中经常会有每天限制次数的需求,这样的功能几乎在每个功能都可能出现,这种功能每个模块自己写又是重复的,因此需要统一处理。

比如:每日抽奖的免费次数,比如每天可打的副本次数等等功能。

今天这篇写一下这个每日次数限制的功能的实现。

1、设计需求

需要任何模块都可以调用,在查询的时候可以自动重置,并且自动入库,并且支持周,月等周期。

2、数据库设计

n_roleId : 玩家id,作为主键

n_reset_type : 枚举,不同的重置类型定义不同的id,作为主键

n_count :当前周期已经使用的数量,每次重置为0

s_extend :扩展字段,每种类型可以存一些自定义的数据到里面

d_update : 更新时间

d_create : 数据创建的时间

3、代码实现

3.1 枚举类型定义
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package org.pdool.dayLimit;

/**
 * 重置次数限制类型
 */
public enum ResetLimitType {
    /**
     * 每日抽奖次数
     */
    LOTTERY_COUNT(1),
    /**
     *  每周收礼次数
     */
    RECEIVE_GIFT_COUNT(2,2),
    ;
    /**
     * 限制类型
     */
    private int limitType;
    /**
     * 重置类型 1 每天 2 每周 3 每月
     */
    private int resetType = 1;

    ResetLimitType(int limitType) {
        this.limitType = limitType;
    }

    ResetLimitType(int limitType, int resetType) {
        this.limitType = limitType;
        this.resetType = resetType;
    }

    public int getLimitType() {
        return limitType;
    }

    public int getResetType() {
        return resetType;
    }

    public static ResetLimitType valueOf(int limitType) {
        for (ResetLimitType resetLimitType : values()) {
            if (limitType == resetLimitType.getLimitType()) {
                return resetLimitType;
            }
        }
        return null;
    }
}

说明:枚举定义了2个构造函数。

默认的构造函数重置类型是1,也就是每日重置。

2个参数的构造函数,可以自定义重置类型,重置类型 1 每天 2 每周 3 每月

3.2 日期函数util
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package org.pdool.dayLimit;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DateUtil {
    /**
     * 判断两个日期是否同一天
     *
     * @param beginDate
     * @param endDate
     * @return
     */
    public static boolean isSameDay(Date beginDate, Date endDate) {
        return getDiffDays(beginDate, endDate) == 0;
    }
    /**
     * 判断两个日期是否同一周
     *
     * @param beginDate
     * @param endDate
     * @return
     */
    public static boolean isSameWeek(Date beginDate, Date endDate) {
        Calendar begin = Calendar.getInstance();
        begin.setTime(beginDate);
        Calendar end = Calendar.getInstance();
        end.setTime(endDate);

        //换算beginDate的周一时间
        int beginDayOfWeek = begin.get(Calendar.DAY_OF_WEEK);
        if (beginDayOfWeek == 1) {
            begin.add(Calendar.DAY_OF_YEAR, -6);
        } else if (beginDayOfWeek > 2) {
            begin.add(Calendar.DAY_OF_YEAR, 2 - beginDayOfWeek);
        }

        //换算endDate的周一时间
        int endDayOfWeek = end.get(Calendar.DAY_OF_WEEK);
        if (endDayOfWeek == 1) {
            end.add(Calendar.DAY_OF_YEAR, -6);
        } else if (endDayOfWeek > 2) {
            end.add(Calendar.DAY_OF_YEAR, 2 - endDayOfWeek);
        }
        return ((end.get(Calendar.YEAR) == begin.get(Calendar.YEAR)) && (end.get(Calendar.DAY_OF_YEAR) == begin.get(Calendar.DAY_OF_YEAR)));
    }

    /**
     * 两个时间相差天数
     *
     * @param beginDate
     * @param endDate
     * @return
     */
    public static int getDiffDays(Date beginDate, Date endDate) {
        Calendar begin = Calendar.getInstance();
        begin.setTime(beginDate);
        begin.set(Calendar.HOUR_OF_DAY, 0);
        begin.set(Calendar.MINUTE, 0);
        begin.set(Calendar.SECOND, 0);
        begin.set(Calendar.MILLISECOND, 0);
        Calendar end = Calendar.getInstance();
        end.setTime(endDate);
        end.set(Calendar.HOUR_OF_DAY, 0);
        end.set(Calendar.MINUTE, 0);
        end.set(Calendar.SECOND, 0);
        end.set(Calendar.MILLISECOND, 0);
        return (int) ((end.getTimeInMillis() - begin.getTimeInMillis()) / (24 * 60 * 60 *1000));
    }


    /**
     * 判断2个时间
     *@param date
     *@param date2
     *@param state  1:比较是否是同一个月,2:比较是否是同一天,3:比较是否是同一年
     *@return boolean
     */
    public static boolean isSameMonth(Date date, Date date2)
    {
        Calendar begin = Calendar.getInstance();
        begin.setTime(date);
        Calendar end = Calendar.getInstance();
        end.setTime(date2);
        return (end.get(Calendar.YEAR) == begin.get(Calendar.YEAR)) && (end.get(Calendar.MONTH) == begin.get(Calendar.MONTH));
    }
}

说明:实现了对天,月 和 周的时间比较,可以判断两个时间是否在同一天,同一周,同一个月。

3.3 重置对象的定义
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package org.pdool.dayLimit;

import java.util.Date;

/**
 * 重置次数
 */
public class ResetCountVO {
    //  角色id
    private int roleId;
    //  重置的类型
    private ResetLimitType resetType;
    //已经消耗次数
    private int num;
    //最后更新时间
    private Date updateTime;
    //扩展信息
    private String extend;

    public int getRoleId() {
        return roleId;
    }

    public void setRoleId(int roleId) {
        this.roleId = roleId;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public String getExtend() {
        return extend;
    }

    public void setExtend(String extend) {
        this.extend = extend;
    }

    public ResetLimitType getResetType() {
        return resetType;
    }

    public void setResetType(ResetLimitType resetType) {
        this.resetType = resetType;
    }

    /**
     * 获得次数
     *
     * @return
     */
    public int getCount() {
        int resetType = this.resetType.getResetType();
        Date now = new Date();
        if (resetType == 1) {
            //  每日重置
            if (DateUtil.isSameDay(now, updateTime)) {
                return this.num;
            }
        } else if (resetType == 2) {
            //  每周重置
            if (DateUtil.isSameWeek(now, updateTime)) {
                return this.num;
            }
        } else if (resetType == 3) {
            //  每月重置
            if (DateUtil.isSameMonth(now, updateTime)) {
                return this.num;
            }
        }
        this.num = 0;
        updateTime = now;
        return 0;
    }

    /**
     * 增加次数
     *
     * @param addCountArg
     * @return
     */
    public int addCount(int... addCountArg) {
        int count = getCount();
        int addCount = 1;
        if (addCountArg.length != 0) {
            addCount = addCountArg[0];
        }
        count += addCount;
        num = count;
        updateTime = new Date();
        return count;
    }


}

说明:重置对象自带的方法比如查和增加次数。

addCount 函数,在不传参数的时候,默认增加次数 1,在当前的基础上增加1 次

传递参数的时候,则使用传递的参数,比如 addCount(50),则在当前的基础上增加50次。

3.4 使用方法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package org.pdool.dayLimit;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class Aain {
    public static void main(String[] args) {
        Map<ResetLimitType,ResetCountVO> playerResetMap = new HashMap<>();
        ResetCountVO resetCountVO1 = new ResetCountVO();
        resetCountVO1.setResetType(ResetLimitType.LOTTERY_COUNT);
        resetCountVO1.setUpdateTime(new Date(1621870616000L));
        resetCountVO1.setNum(1);
        playerResetMap.put(ResetLimitType.LOTTERY_COUNT,resetCountVO1 );

        ResetCountVO resetCountVO2 = new ResetCountVO();
        resetCountVO2.setResetType(ResetLimitType.RECEIVE_GIFT_COUNT);
        resetCountVO2.setUpdateTime(new Date(1621870616000L));
        resetCountVO2.setNum(1000);
        playerResetMap.put(ResetLimitType.RECEIVE_GIFT_COUNT,resetCountVO2 );

        int count = resetCountVO1.getCount();
        System.out.println(count);

        int count2 = resetCountVO2.getCount();
        System.out.println(count2);
    }
}
3.5 注意事项

1、没有实现数据的入库操作,这个在使用代码的时候,需要根据自己的项目进行更改。

2、没有封装在枚举类型对应的对象不存在时自动创建操作,可以根据自己的项目代码规则自己实现

在上面的我定义了一个map ,可以使用 下面的代码进行封装实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 ResetCountVO resetCountVO = playerResetMap.computeIfAbsent(ResetLimitType.LOTTERY_COUNT, k -> new ResetCountVO());
        if (resetCountVO.getUpdateTime() == null){
            resetCountVO.setResetType(ResetLimitType.LOTTERY_COUNT);
            resetCountVO.setUpdateTime(new Date(1621870616000L));
            resetCountVO.setNum(1);
        }

4、总结

周期性的限制次数的思想很简单,就是任何需要访问数量的地方进行次数重置检测。

我们要做的就是怎么实现的的简单方便,将逻辑进行封装的更顺手。

好了,今天就写到这吧,睡觉。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 香菜聊游戏 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
BSP英制管螺纹详解
数控编程、车铣复合、普车加工、Mastercam、行业前沿、机械视频,生产工艺、加工中心、模具、数控等前沿资讯在这里等你哦
lrglu
2024/06/28
4.3K0
BSP英制管螺纹详解
攻丝前孔尺寸的计算详解
数控编程、车铣复合、普车加工、Mastercam、行业前沿、机械视频,生产工艺、加工中心、模具、数控等前沿资讯在这里等你哦
lrglu
2024/06/11
1930
攻丝前孔尺寸的计算详解
G32车螺纹详解
数控编程、车铣复合、普车加工、行业前沿、机械视频,生产工艺、加工中心、模具、数控等前沿资讯在这里等你哦
lrglu
2023/09/04
7760
G32车螺纹详解
英制螺纹UNC/UNF/UNEF
数控编程、车铣复合、普车加工、Mastercam、行业前沿、机械视频,生产工艺、加工中心、模具、数控等前沿资讯在这里等你哦
lrglu
2024/05/28
6510
英制螺纹UNC/UNF/UNEF
圆锥管螺纹计算及G92车削编程
圆锥管螺纹英制螺纹,一般应按标准组织生产。管子螺纹部分的锥度是1:16,其斜角(单面角度)为1°47'24”,牙形角为55°和60°。现以60°圆锥管螺纹(NPT)为例,将各部分尺寸计算公式见表1。
lrglu
2022/06/30
3.3K0
圆锥管螺纹计算及G92车削编程
广数车床G代码全解
其中: X(U),Z(W)为定位的终点坐标,X,Z分别为X轴和Z轴的绝对坐标,U,W分别为X轴和Z轴的相对坐标,、相对坐标和绝对坐标用其中之一,不需移位的坐标轴可以省略,相对坐标是相对于当前位置的位移量。
lrglu
2022/03/30
2.3K0
广数车床G代码全解
几何公差干货全集,速收藏!
彻底理解几何公差的符号及管控意义,并正确理解尺寸公差的概念,是一件非常困难的事情。
lrglu
2022/12/05
1.4K0
几何公差干货全集,速收藏!
《公差配合与技术测量》复习题
1、 所谓互换性,就是___ ____的零部件,在装配时_______________________,就能装配到机器或仪器上,并满足___________的特性。
用户7505898
2020/07/19
3.1K0
十二条数控加工经验总结
数控编程、车铣复合、普车加工、Mastercam、行业前沿、机械视频,生产工艺、加工中心、模具、数控等前沿资讯在这里等你哦
lrglu
2024/05/17
1660
十二条数控加工经验总结
常用管螺纹特征及区别
我们知道管螺纹的种类很多,标准很杂,很多不清楚种类,更别提编程加工了,下面我们首先看下管螺纹的种类及相对应的国标。
lrglu
2022/05/16
2K0
常用管螺纹特征及区别
机械人必备,丝锥选型、断裂分析大全
  它通用性最强,切削锥部分可以有2、4、6牙,短锥用于不通孔,长锥用于通孔。只要底孔足够深,就应尽量选用切削锥长一些的,这样分担切削负荷的齿多一些,使用寿命也长一些。
lrglu
2022/03/30
1.3K0
机械人必备,丝锥选型、断裂分析大全
夹头的选择
圆柱直柄均匀夹紧,用于确保铣削、钻削和铰削的最佳跳动精度。不带平面或锁紧功能时,对扭矩和轴向力是有限制的,超出这个限制会造成刀具在夹头中移位。
lrglu
2024/07/10
1510
夹头的选择
用G76指令如何车梯形螺纹?
梯形螺纹的代号用字母“Tr”及公称直径×螺距表示,单位均为mm。左旋螺纹需在尺寸规格之后加注“LH”,右旋则不用标注。例如Tr36×6,T44×8LH等。梯形螺纹各基本尺寸计算公式可通过机械加工手册查阅。
lrglu
2022/06/30
4.1K0
用G76指令如何车梯形螺纹?
《公差配合与技术测量》试题答案卷
(A) 上偏差, 正值(B) 上偏差,负值(C)下偏差, 正值(D) 下偏差, 负值
用户7505898
2020/08/09
2.2K0
《公差配合与技术测量》试题答案卷
常用公差及配合
1.1.1 零线---在极限与配合图解中,表示基本尺寸的一条直线.以其为基准确定偏差和公差;
用户7505898
2020/07/03
2.5K0
常用公差及配合
数控车床加工普通螺纹的四个技术要点!
在数控车床上可以车削米制、英寸制、模数和径节制四种标准螺纹,无论车削哪一种螺纹,车床主轴与刀具之间必须保持严格的运动关系:即主轴每转一转(即工件转一转),刀具应均匀地移动一个(工件的)导程的距离。以下通过对普通螺纹的分析,加强对普通螺纹的了解,以便更好的加工普通螺纹。
lrglu
2022/06/30
1.1K0
数控车床加工普通螺纹的四个技术要点!
如何降低数控加工成本
数控编程、车铣复合、普车加工、Mastercam、行业前沿、机械视频,生产工艺、加工中心、模具、数控等前沿资讯在这里等你哦
lrglu
2024/05/11
2050
如何降低数控加工成本
圆柱和圆锥螺纹铣削
数控编程、车铣复合、普车加工、Mastercam、行业前沿、机械视频,生产工艺、加工中心、模具、数控等前沿资讯在这里等你哦
lrglu
2024/07/10
1330
圆柱和圆锥螺纹铣削
翼型零件的5轴铣削工艺
数控编程、车铣复合、普车加工、Mastercam、行业前沿、机械视频,生产工艺、加工中心、模具、数控等前沿资讯在这里等你哦
lrglu
2023/12/19
1770
翼型零件的5轴铣削工艺
工业镜头参数
机器视觉系统中,镜头作为机器的眼睛,其主要作用是将目标物体的图像聚焦在图像传感器(相机)的光敏器件上。数据系统所处理的所有图像信息均需要通过镜头得到,镜头的质量直接影响到视觉系统的整体性能。
vv彭
2021/07/08
1.2K0
相关推荐
BSP英制管螺纹详解
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验