本帖最后由 南外丶仓鼠 于 2021-2-8 18:19 编辑
代码:复制代码其中
percent=0.3
speed=30
代码目的:
当服务器某世界夜晚时,睡觉的玩家超过一定占比,夜晚时间开始加速流动,直到白天结束睡觉
出现的问题:
从12600刻(下午六点左右)一部分玩家开始睡觉,加速流逝到16400刻左右时,突然地睡觉的一部分玩家突然停止睡觉,时间跳到第二天0刻(上午6点)于是我尝试从16400刻开始入睡,结果时间加速流逝到18200刻左右,又出现了上面的情况。
这说明我代码的加速判定是没问题的。
但是当时的确服务器内有两名玩家在线,其中有一位不在睡觉,essentials也没有判定其为afk(挂机状态),但是时间就像是所有人在睡觉一样突然的跳到第二天
我算了一下,从入睡到结束睡眠大致等于MC原版单人模式从入睡到第二天经过的现实时间(8-10s左右)
我的猜测:
bukkit判定睡眠是根据ip(因为当时服务器内两名玩家都是我的测试号,同IP)
请求各位大佬解答,感激不尽
代码:
- public class QuickNight {
- private static YamlConfiguration yaml;
- private static double percent;
- private static int speed;
- private static boolean title;
- public QuickNight() {
- File file = new File(UntilTheEndServer.getInstance().getDataFolder(), "timeoperate.yml");
- if (!file.exists())
- UntilTheEndServer.getInstance().saveResource("timeoperate.yml", false);
- yaml = YamlConfiguration.loadConfiguration(file);
- if (!yaml.getBoolean("quickNight.enable"))
- return;
- percent = yaml.getDouble("quickNight.percent");
- speed = yaml.getInt("quickNight.speed");
- title = yaml.getBoolean("quickNight.title");
- new BukkitRunnable() {
- @Override
- public void run() {
- for (World world : Bukkit.getWorlds()) {
- //白天不进行计算
- if (world.getTime() < 12600) {
- continue;
- }
- //计算某世界总睡觉玩家人数
- int amount = 0;
- if (world.getPlayers().size() == 0) {
- continue;
- }
- for (Player player : world.getPlayers()) {
- if (player.isSleeping()) {
- amount++;
- }
- }
- //如果全部都在入睡,就按原版机制跳到第二天
- if (amount == world.getPlayers().size()) {
- continue;
- }
- //如果入睡人数超过占比,则加速时间流动
- if (amount >= world.getPlayers().size() * percent) {
- long newTime = world.getTime() + 2 * (speed - 1);
- System.out.println(newTime);
- if (newTime >= 24000) {
- world.setTime(newTime - 24000);
- } else {
- world.setTime(newTime);
- }
- //告诉玩家几点了
- if (title) {
- for (Player player : world.getPlayers()) {
- player.resetTitle();
- player.sendTitle("§a" + getFormatTime(newTime), "§e世界时间");
- }
- }
- }
- }
- }
- }.runTaskTimer(UntilTheEndServer.getInstance(), 0L, 2L);
- }
- //把世界时间刻变为刻度的hh:mm
- private static String getFormatTime(long newTime) {
- long hour = newTime / 1000;
- long minute = (long) (newTime % 1000 * 0.06);
- String tmp = "";
- if (minute < 10) {
- tmp += "0" + minute;
- } else {
- tmp += minute;
- }
- if (hour + 6 >= 24) {
- return "0" + (hour + 6 - 24) + ":" + tmp;
- } else {
- return (hour + 6) + ":" + tmp;
- }
- }
- }
percent=0.3
speed=30
代码目的:
当服务器某世界夜晚时,睡觉的玩家超过一定占比,夜晚时间开始加速流动,直到白天结束睡觉
出现的问题:
从12600刻(下午六点左右)一部分玩家开始睡觉,加速流逝到16400刻左右时,突然地睡觉的一部分玩家突然停止睡觉,时间跳到第二天0刻(上午6点)于是我尝试从16400刻开始入睡,结果时间加速流逝到18200刻左右,又出现了上面的情况。
这说明我代码的加速判定是没问题的。
但是当时的确服务器内有两名玩家在线,其中有一位不在睡觉,essentials也没有判定其为afk(挂机状态),但是时间就像是所有人在睡觉一样突然的跳到第二天
我算了一下,从入睡到结束睡眠大致等于MC原版单人模式从入睡到第二天经过的现实时间(8-10s左右)
我的猜测:
bukkit判定睡眠是根据ip(因为当时服务器内两名玩家都是我的测试号,同IP)
请求各位大佬解答,感激不尽
本帖最后由 南柯郡守 于 2021-2-9 00:02 编辑
1. 判定玩家睡觉跳时间并不是判断ip 因为Player下有个setSleepingIgnored(boolean isSleeping)
2. 你说的 突然跳到0刻 是一个在睡觉一个没睡觉的情况下跳到0刻的嘛
你这个不就是相当于直接跳到0刻嘛
1. 判定玩家睡觉跳时间并不是判断ip 因为Player下有个setSleepingIgnored(boolean isSleeping)
- if (newTime >= 24000) {
- world.setTime(newTime - 24000);
- }
你这个不就是相当于直接跳到0刻嘛
本帖最后由 洞穴夜莺 于 2021-2-9 00:11 编辑
那不一样
>=又不是==
我倒是觉得楼主应该把整个项目发上来
而且时间k和k + 24000是不同的时间,你不能这样处理的
南柯郡守 发表于 2021-2-8 23:59
1. 判定玩家睡觉跳时间并不是判断ip 因为Player下有个setSleepingIgnored(boolean isSleeping)
2. 你说 ...
那不一样
>=又不是==
我倒是觉得楼主应该把整个项目发上来
而且时间k和k + 24000是不同的时间,你不能这样处理的
洞穴夜莺 发表于 2021-2-9 00:04
那不一样
>=又不是==
24001-24000=1
那不就是把世界时间设置为1刻
那天不就亮了 那玩家不就自动起床了
我觉得基本上没问题 就是流速倍数太大了
还有一件事
最好是在加速刚开始的时候把时间流动先停掉
不然你在这加速 他自己也在跑
最后速度肯定是比预期快的
最好是在加速刚开始的时候把时间流动先停掉
不然你在这加速 他自己也在跑
最后速度肯定是比预期快的
南柯郡守 发表于 2021-2-9 00:11
24001-24000=1
那不就是把世界时间设置为1刻
我调试的时候看着时间流逝,到连2w都没到就停了
即使是20倍速也不可能10秒过完晚上啊
我是百思不得其解才去测出游戏刻数据的
南柯郡守 发表于 2021-2-8 23:59
1. 判定玩家睡觉跳时间并不是判断ip 因为Player下有个setSleepingIgnored(boolean isSleeping)
2. 你说 ...
我曾将sleepingignore设为false
没有作用😭
洞穴夜莺 发表于 2021-2-9 00:04
那不一样
>=又不是==
项目在https://github.com/HamsterYDS/UntilTheEndServer
其中有两个模块会操纵时间,都在utes.timeoperate下
我测试加速夜晚的时候,另一个模块是disable状态,应该不会有影响
本帖最后由 南柯郡守 于 2021-2-9 00:28 编辑
24000-16400=7600tick
7600÷20=380秒
原本过完夜晚需要380秒(6分多钟)
2 * (speed - 1)
已知speed=30
即 1tick=58tick
你算算速度放大了多少倍
尝试从16400刻开始入睡...
...结果时间加速流逝到18200刻左右
把时间流动先停掉.....
...最后速度肯定是比预期快的
24000-16400=7600tick
7600÷20=380秒
原本过完夜晚需要380秒(6分多钟)
2 * (speed - 1)
已知speed=30
即 1tick=58tick
你算算速度放大了多少倍
南柯郡守 发表于 2021-2-9 00:16
还有一件事
最好是在加速刚开始的时候把时间流动先停掉
初始化的时候已经setdaylightcycle false了
算出来过一晚上大概需要30秒,但是连其一半时间都没到,睡觉就停止了
我是看着每刻tick的数值变化的,到16000就突然停了,然后跳到24000也就是下一天的0
本帖最后由 南柯郡守 于 2021-2-9 00:49 编辑
7600 tick ÷ (20 x 1tick x 58) ≈ 6.55秒
不到7秒就跑过7600tick了
1tick=58tick 相当于一秒跑了1160tick 七秒天就亮了
就是说 你16400刻开始睡觉算
需要7600tick天才会亮
你speed=30 直接把速度翻了58倍
原本7600刻需要380秒跑完
现在只用不到7秒就跑完了
即便是12600刻计算入睡开始加速
24000-12600=11400 tick
11400÷20=570 秒
加速58倍之后
570 秒 ÷ 58 ≈ 9.83 秒
也不超过十秒
所以你说的
其实没毛病
至于你说的
确实有点迷
不过建议直接System.out.println(world.getTime());看看
哦 你这是2刻执行一次啊
问题不大 7*2 =14 10*2=20 都差不多
南外丶仓鼠 发表于 2021-2-9 00:31
初始化的时候已经setdaylightcycle false了
算出来过一晚上大概需要30秒,但是连其一半时间都没到,睡觉 ...
7600 tick ÷ (20 x 1tick x 58) ≈ 6.55秒
不到7秒就跑过7600tick了
1tick=58tick 相当于一秒跑了1160tick 七秒天就亮了
就是说 你16400刻开始睡觉算
需要7600tick天才会亮
你speed=30 直接把速度翻了58倍
原本7600刻需要380秒跑完
现在只用不到7秒就跑完了
即便是12600刻计算入睡开始加速
24000-12600=11400 tick
11400÷20=570 秒
加速58倍之后
570 秒 ÷ 58 ≈ 9.83 秒
也不超过十秒
所以你说的
算出来过一晚上大概需要30秒,但是连其一半时间都没到,睡觉就停止了
其实没毛病
至于你说的
每刻tick的数值变化的,到16000就突然停了
确实有点迷
不过建议直接System.out.println(world.getTime());看看
哦 你这是2刻执行一次啊
问题不大 7*2 =14 10*2=20 都差不多
南柯郡守 发表于 2021-2-9 00:38
7600 tick ÷ (20 x 1tick x 58) ≈ 6.55秒
不到7秒就跑过7600tick了
代码中已经有System.out了
我调了半天,硬是连个大于2w的数没看到,而且天色的确是由全黑到全白,非常突兀,没有清晨的效果
南柯郡守 发表于 2021-2-9 00:38
7600 tick ÷ (20 x 1tick x 58) ≈ 6.55秒
不到7秒就跑过7600tick了
明天录个视频
感谢大佬不断跟踪帮助谢谢🙏🙏
本帖最后由 南外丶仓鼠 于 2021-2-9 08:42 编辑
录屏
https://www.bilibili.com/blackboard/newplayer.html?playlist=false&crossDomain=1&aid=801559789&page=1
@南柯郡守
录屏
https://www.bilibili.com/blackboard/newplayer.html?playlist=false&crossDomain=1&aid=801559789&page=1
@南柯郡守
本帖最后由 南柯郡守 于 2021-2-9 14:24 编辑
我直接用你的代码稍加修改后测试了
这是视频(没发小破站 审核太久)
https://cowtransfer.com/s/b7709b3567b841
以下是代码实现
复制代码
我看视频 你将时间设置在12600之后 开始睡觉的第一个输出时间是12700+
所以你时间流逝并没有关掉
我直接用你的代码稍加修改后测试了
这是视频(没发小破站 审核太久)
https://cowtransfer.com/s/b7709b3567b841
以下是代码实现
- package top.themeda.ancientworld.runnable;
- import org.bukkit.Bukkit;
- import org.bukkit.World;
- import org.bukkit.entity.Player;
- import org.bukkit.scheduler.BukkitRunnable;
- import top.themeda.ancientworld.Core;
- public class TimeBoost {
- private static double percent;
- private static int speed;
- private static boolean title;
- public TimeBoost(){
-
- percent = 0.5d;
- speed = 20;
- title=true;
- new BukkitRunnable() {
- @Override
- public void run() {
- for (World world : Bukkit.getWorlds()) {
- //白天不进行计算
- if (world.getTime() < 12600) {
- continue;
- }
- //计算某世界总睡觉玩家人数
- int amount = 0;
- if (world.getPlayers().size() == 0) {
- continue;
- }
- for (Player player : world.getPlayers()) {
- if (player.isSleeping()) {
- amount++;
- }
- }
- //如果全部都在入睡,就按原版机制跳到第二天
- if (amount == world.getPlayers().size()) {
- continue;//草! 无良论坛吞我代码
- //多开一行。 你这里如果真的关了时间流逝 那么所有玩家都睡觉也不会使得时间跳到第二天
- }
- //如果入睡人数超过占比,则加速时间流动
- if (amount >= world.getPlayers().size() * percent) {
- long newTime = world.getTime() + 2 * speed;
- System.out.println(newTime);
- if (newTime >= 24000) {
- world.setTime(newTime - 24000);
- } else {
- world.setTime(newTime);
- }
- //告诉玩家几点了
- if (title) {
- for (Player player : world.getPlayers()) {
- player.resetTitle();
- player.sendTitle("§a" + newTime, "§e世界时间",10,20,10);
- }
- }
- }
- }
- }
- }.runTaskTimer(Core.getInstance(), 0L, 2L);
- }
- }
我看视频 你将时间设置在12600之后 开始睡觉的第一个输出时间是12700+
所以你时间流逝并没有关掉
南柯郡守 发表于 2021-2-9 14:20
我直接用你的代码稍加修改后测试了
这是视频(没发小破站 审核太久)
https://cowtransfer.com/s/b7709b3567b ...
原来如此,我差个setdaylightcycle
实在感谢
但是仍有一个问题,为什么一个玩家不在睡觉,仍然执行了原版的机制
南外丶仓鼠 发表于 2021-2-9 18:42
原来如此,我差个setdaylightcycle
实在感谢
但是仍有一个问题,为什么一个玩家不在睡觉,仍然执行了原版 ...
无法复现 所以暂时无法得出结论
还有一件事
你冻结时间自然流动之后你要手动操作他以正常速度流动
不然没有玩家睡觉那黑夜总会是黑夜