别在网上乱找代码了,找了一段代码突然爆了!!!

news/2024/7/9 17:23:34 标签: 游戏, 编程语言, bug, epoll, 算法导论

本人是做游戏服务器开发的,碰到一个需求,给符某些要求的玩家的发送道具奖励,奖励的数量根据离线的天数计算。

这个需求实现起来很简单,只需要在玩家上线的时候计算上次离线时间和当前时间间隔的天数,然后根据策划的算法,计算出道具种类与数量,发一封邮件给玩家就可以了。

计算两个时间间隔天数的函数没有现成的,自己又懒得写,就上谷歌搜了下,选了第一条结果,代码如下:

public static int differentDays(Date date1,Date date2){
    Calendar cal1 = Calendar.getInstance();
    cal1.setTime(date1);

    Calendar cal2 = Calendar.getInstance();
    cal2.setTime(date2);
    int day1= cal1.get(Calendar.DAY_OF_YEAR);
    int day2 = cal2.get(Calendar.DAY_OF_YEAR);

    int year1 = cal1.get(Calendar.YEAR);
    int year2 = cal2.get(Calendar.YEAR);
    if(year1 != year2)   //同一年
    {
        int timeDistance = 0 ;
        for(int i = year1 ; i < year2 ; i ++)
        {
            if(i%4==0 && i%100!=0 || i%400==0)    //闰年            
            {
                timeDistance += 366;
            }
            else    //不是闰年
            {
                timeDistance += 365;
            }
        }

        return timeDistance + (day2-day1) ;
    }
    else    //不同年
    {
        System.out.println("判断day2 - day1 : " + (day2-day1));
        return day2-day1;
    }
}

代码来源:www.cnblogs.com/0201zcr/p/5000977.html

把代码复制到项目里,调试下,发现没问题就直接用了,毕竟谷歌结果第一名,放心。

这段代码跑了几个月一直没问题,但是到了2020-1-1日那天,有玩家反馈收到了几百封奖励邮件,高兴坏了,但是出于对游戏的热爱,还是通知了运营人员。

运营把BUG反馈到服务器这边后我开始排查,百思不得其解的是最近几天都没有更新服务器, 而前几天服务器都稳稳地,怎么突然就出BUG了呢。

接下来就是分析玩家数据,结合代码逻辑确定问题所在,最终根据BUG的表现排除了所有可能性后,发现唯一可能出问题的地方就是那个网上复制过来的计算天数差的函数。

根据调试发现,这个函数在两个日期参数是不同的年份并且第一个日期大于第二个日期的时候,会返回一个错误的结果

比如:

differentDays("2020-1-1","2019-12-25")

理论上这么调用正确的结果是 -7,但是因为函数有BUG,调用结果是 358

于是本来不用发奖励,因为这种特殊情况一下子发出去358份,严重影响了游戏某类道具的平衡性。

至于补救方式就是统计名单,把发出去但还没有用掉的道具回收,用掉的就当福利,然后再发公告道歉,再送些其他物品弥补。

也幸好补救的及时,要是这些道具收不回来,游戏运营的策略都要大变了,我特么肯定没好果子吃了。

所以千万别在网上复制来路不明的代码乱用,如果真的要用,必须反复测试,否则哪一天突然暴雷有你受的。

改用Java8的日期库修复了BUG:

public static int differentDays(Date date1, Date date2) {
    if (date1 == null || date2 == null) {
        throw new RuntimeException("日期不能为空");
    }
    LocalDate localDate1 = date2LocalDate(date1);
    LocalDate localDate2 = date2LocalDate(date2);
    return Generic.long2int(localDate1.until(localDate2, ChronoUnit.DAYS));
}

public static LocalDate date2LocalDate(Date date) {
    Instant instant = date.toInstant();
    ZoneId zoneId = ZoneId.systemDefault();
    LocalDate localDate = instant.atZone(zoneId).toLocalDate();
    return localDate;
}

作者:陈宏鸿

来源:https://urlify.cn/Mfe6Rz

往期精彩回顾

让人又爱又恨的 Lombok,到底该不该用

Delombok 是个啥?居然可破 Lombok?

跳槽的必要条件是有一份好的简历

时候为自己的后半生考虑了——致奔三的互联网人

点个赞呗


http://www.niftyadmin.cn/n/1332321.html

相关文章

互联网公司忽悠员工的黑话,套路太深了。。。

据说这些是互联网公司招工时忽悠的黑话&#xff0c;大家来看看是不是真的&#xff1f;再列举几个黑话&#xff1a;老板&#xff1a;产品&#xff1a;程序员&#xff1a;据说这些是互联网公司招工时忽悠的黑话&#xff0c;大家来看看是不是真的&#xff1f;再列举几个黑话&#…

sqlserver 2019 群集加固

详见CIS加固文档 链接&#xff1a;https://pan.baidu.com/s/1xILe1bn8r7BBlKG_Us4CsQ 提取码&#xff1a;qv8d

不要再自己封装各种Util工具类了,这款神仙级框架你值得拥有!

来源&#xff1a;ryanc.cc/archives/hutool-java-tools-lib作者&#xff1a;Ryan Wang简介Hutool 谐音 “糊涂”&#xff0c;寓意追求 “万事都作糊涂观&#xff0c;无所谓失&#xff0c;无所谓得” 的境界。Hutool 是一个 Java 工具包&#xff0c;也只是一个工具包&#xff0c…

An operation on a socket could not be performed because the system lacked sufficient buffer space or

dkron &#xff08;dkron 是一个定时任务执行系统&#xff0c;可以将所有的定时任务写成接口形式&#xff0c;用这个定时任务系统统一管理&#xff09;定时任务所有的定时任务都不执行了&#xff0c;启动不了&#xff0c;查看日志报错: An operation on a socket could not be …

15000 字的 SQL 语句大全

点击上方 果汁简历 &#xff0c;选择“置顶公众号”优质文章&#xff0c;第一时间送达一、基础1、说明&#xff1a;创建数据库CREATE DATABASE database-name2、说明&#xff1a;删除数据库drop database dbname3、说明&#xff1a;备份sql server--- 创建 备份数据的 deviceUS…

关于sqlserver always on群集创建登录名和数据库用户名丢失关联

最近部署遇到一个问题&#xff0c;在always on 群集主节点用ssms工具创建登录名&#xff0c;然后故障故障转移到从节点创建登录名&#xff0c;用 sp_change_users_login 关联后&#xff0c;先前主节点登录名和数据库用户名就会丢失关联&#xff0c;这样集群就会有问题 经调查&…

朋友入职中软一个月(外包华为)就离职了!

点击上方 果汁简历 &#xff0c;选择“置顶公众号”优质文章&#xff0c;第一时间送达我在年前从上一家公司离职&#xff0c;没想到过年期间疫情爆发&#xff0c;我也被困在家里&#xff0c;在家呆着的日子让人很焦躁&#xff0c;于是我疯狂的投简历&#xff0c;看面试题&#…

navicat 连接sqlsever报错:客户端不支持加密/encryption not supported on the client

最近navicat 连接sqlserver 突然连接不上了&#xff0c;telnet sqlserver端口能通 报错如下&#xff1a; 这种情况一般是navicat的sqlserver客户端损坏了&#xff0c;所以需要将客户端卸载&#xff0c;重装 打开windows 卸载程序 然后重新连接sqlserver &#xff0c;会让你重…