Advance world clock between updates
This commit is contained in:
@@ -420,6 +420,9 @@ def start_automation(global_state, initialize=True):
|
|||||||
g.protocol_version = 777
|
g.protocol_version = 777
|
||||||
if initialize:
|
if initialize:
|
||||||
g.time = 0.0
|
g.time = 0.0
|
||||||
|
g.time_base = None
|
||||||
|
g.time_update_received_at = None
|
||||||
|
g.clock_rate = 1.0
|
||||||
g.path = []
|
g.path = []
|
||||||
g.look_at = None
|
g.look_at = None
|
||||||
g.y_v = 0.0
|
g.y_v = 0.0
|
||||||
@@ -505,6 +508,9 @@ def start_automation(global_state, initialize=True):
|
|||||||
g.get('connection') and g.connection.connected):
|
g.get('connection') and g.connection.connected):
|
||||||
started = time.monotonic()
|
started = time.monotonic()
|
||||||
now = time.monotonic()
|
now = time.monotonic()
|
||||||
|
game = g.get('game')
|
||||||
|
if game is not None:
|
||||||
|
game._advance_world_time()
|
||||||
if not initial_world_ready:
|
if not initial_world_ready:
|
||||||
if not bot.missing_movement_chunks(g):
|
if not bot.missing_movement_chunks(g):
|
||||||
if loaded_since is None:
|
if loaded_since is None:
|
||||||
|
|||||||
+1
-1
@@ -221,7 +221,7 @@ class Commands:
|
|||||||
seconds = self.g.time * 3.6
|
seconds = self.g.time * 3.6
|
||||||
start = datetime(2000, 1, 1, hour=6)
|
start = datetime(2000, 1, 1, hour=6)
|
||||||
mctime = start + timedelta(seconds=seconds)
|
mctime = start + timedelta(seconds=seconds)
|
||||||
reply = str(self.g.time) + ' - ' + mctime.strftime('%I:%M %p')
|
reply = str(int(self.g.time)) + ' - ' + mctime.strftime('%I:%M %p')
|
||||||
|
|
||||||
## !count [id] - counts the number of items with that id
|
## !count [id] - counts the number of items with that id
|
||||||
if command == 'count' and data:
|
if command == 'count' and data:
|
||||||
|
|||||||
+24
-3
@@ -179,9 +179,24 @@ class LegacyGame:
|
|||||||
self.g.holding = (item.item_id if item and
|
self.g.holding = (item.item_id if item and
|
||||||
getattr(item, 'present', False) else 0)
|
getattr(item, 'present', False) else 0)
|
||||||
|
|
||||||
|
def _set_world_clock(self, total_ticks, partial_tick=0.0, rate=1.0):
|
||||||
|
self.g.time_base = float(total_ticks) + float(partial_tick)
|
||||||
|
self.g.clock_rate = float(rate)
|
||||||
|
self.g.time_update_received_at = time.monotonic()
|
||||||
|
self._advance_world_time()
|
||||||
|
|
||||||
|
def _advance_world_time(self):
|
||||||
|
received_at = self.g.get('time_update_received_at')
|
||||||
|
time_base = self.g.get('time_base')
|
||||||
|
if received_at is None or time_base is None:
|
||||||
|
return
|
||||||
|
elapsed_ticks = max(0.0, time.monotonic() - received_at) / utils.TICK
|
||||||
|
self.g.time = (time_base + elapsed_ticks *
|
||||||
|
self.g.get('clock_rate', 1.0)) % 24000
|
||||||
|
|
||||||
def handle_time_update(self, packet):
|
def handle_time_update(self, packet):
|
||||||
if hasattr(packet, 'time_of_day'):
|
if hasattr(packet, 'time_of_day'):
|
||||||
self.g.time = packet.time_of_day % 24000
|
self._set_world_clock(packet.time_of_day)
|
||||||
return
|
return
|
||||||
|
|
||||||
updates = getattr(packet, 'clock_updates', ())
|
updates = getattr(packet, 'clock_updates', ())
|
||||||
@@ -201,11 +216,12 @@ class LegacyGame:
|
|||||||
'minecraft:') in (dimension, 'overworld')
|
'minecraft:') in (dimension, 'overworld')
|
||||||
]
|
]
|
||||||
update = preferred[0] if preferred else updates[0]
|
update = preferred[0] if preferred else updates[0]
|
||||||
self.g.time = update['total_ticks'] % 24000
|
|
||||||
self.g.clock_id = update['clock_id']
|
self.g.clock_id = update['clock_id']
|
||||||
self.g.clock_name = clock_names.get(update['clock_id'])
|
self.g.clock_name = clock_names.get(update['clock_id'])
|
||||||
self.g.clock_rate = update['rate']
|
|
||||||
self.g.world_age = packet.age
|
self.g.world_age = packet.age
|
||||||
|
self._set_world_clock(update['total_ticks'],
|
||||||
|
update.get('partial_tick', 0.0),
|
||||||
|
update.get('rate', 1.0))
|
||||||
|
|
||||||
def handle_set_slot(self, packet):
|
def handle_set_slot(self, packet):
|
||||||
g = self.g
|
g = self.g
|
||||||
@@ -700,6 +716,10 @@ class Game(LegacyGame):
|
|||||||
self.g.connection.register_packet_listener(
|
self.g.connection.register_packet_listener(
|
||||||
self.handle_set_held_slot, SetHeldSlotPacket)
|
self.handle_set_held_slot, SetHeldSlotPacket)
|
||||||
|
|
||||||
|
self.g.setdefault('time_base', None)
|
||||||
|
self.g.setdefault('time_update_received_at', None)
|
||||||
|
self.g.setdefault('clock_rate', 1.0)
|
||||||
|
|
||||||
if not self.g.get('health_update_received', False):
|
if not self.g.get('health_update_received', False):
|
||||||
self.g.health = None
|
self.g.health = None
|
||||||
self.g.food = None
|
self.g.food = None
|
||||||
@@ -1222,6 +1242,7 @@ class Game(LegacyGame):
|
|||||||
self.g.drain_dropped), flush=True)
|
self.g.drain_dropped), flush=True)
|
||||||
|
|
||||||
def tick(self):
|
def tick(self):
|
||||||
|
self._advance_world_time()
|
||||||
self._tick_single_drop()
|
self._tick_single_drop()
|
||||||
if self.g.get('dumping') is not None:
|
if self.g.get('dumping') is not None:
|
||||||
self._tick_dump()
|
self._tick_dump()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import io
|
import io
|
||||||
import unittest
|
import unittest
|
||||||
from contextlib import redirect_stdout
|
from contextlib import redirect_stdout
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
from munch import Munch
|
from munch import Munch
|
||||||
from minecraft.networking.packets import PacketBuffer
|
from minecraft.networking.packets import PacketBuffer
|
||||||
@@ -96,6 +97,33 @@ class TestSleepWithBed(unittest.TestCase):
|
|||||||
'partial_tick': 0.5, 'rate': 1.0,
|
'partial_tick': 0.5, 'rate': 1.0,
|
||||||
}])
|
}])
|
||||||
|
|
||||||
|
def test_game_advances_world_clock_between_server_updates(self):
|
||||||
|
game = Game.__new__(Game)
|
||||||
|
game.g = Munch(
|
||||||
|
time_base=None, time_update_received_at=None, clock_rate=1.0,
|
||||||
|
time=0.0,
|
||||||
|
connection=Munch(registry_ids={'minecraft:world_clock': {
|
||||||
|
'minecraft:the_end': 1,
|
||||||
|
'minecraft:overworld': 0,
|
||||||
|
}}),
|
||||||
|
dimension='overworld')
|
||||||
|
packet = Munch(age=900000, clock_updates=[
|
||||||
|
{'clock_id': 1, 'total_ticks': 6000,
|
||||||
|
'partial_tick': 0.0, 'rate': 1.0},
|
||||||
|
{'clock_id': 0, 'total_ticks': 13000,
|
||||||
|
'partial_tick': 0.5, 'rate': 1.0},
|
||||||
|
])
|
||||||
|
|
||||||
|
with patch('mosfet.game.time.monotonic', return_value=100.0):
|
||||||
|
game.handle_time_update(packet)
|
||||||
|
self.assertEqual(game.g.time, 13000.5)
|
||||||
|
self.assertEqual(game.g.clock_name, 'minecraft:overworld')
|
||||||
|
|
||||||
|
with patch('mosfet.game.time.monotonic', return_value=100.5):
|
||||||
|
game._advance_world_time()
|
||||||
|
|
||||||
|
self.assertEqual(game.g.time, 13010.5)
|
||||||
|
|
||||||
def test_player_command_encodes_stop_sleeping(self):
|
def test_player_command_encodes_stop_sleeping(self):
|
||||||
packet = PlayerCommandPacket(
|
packet = PlayerCommandPacket(
|
||||||
entity_id=7, action_id=0, jump_boost=0)
|
entity_id=7, action_id=0, jump_boost=0)
|
||||||
|
|||||||
Reference in New Issue
Block a user