time_utils.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #! /usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # SPDX-FileCopyrightText: Copyright (C) 2021-2022 MH3SP Server Project
  4. # SPDX-License-Identifier: AGPL-3.0-or-later
  5. """Monster Hunter time utils module."""
  6. import datetime
  7. import time
  8. EPOCH = datetime.datetime(1970, 1, 1)
  9. TICKS_PER_CYCLE = 23040 # 6.4 hours per cycle, 3.2 hours per daytime/nighttime
  10. SECONDS_PER_DAY = 24*60*60
  11. JHEN_EVENT_OFFSET = 14 # Cycle of 14 (real) days
  12. FOG_START = 0
  13. JHEN_START = 1 # 1 (real) day of fog
  14. JHEN_END = 3 # Followed by 2 (real) days of sandstorm
  15. def datetime_to_int(dt):
  16. return int((dt - EPOCH).total_seconds())
  17. def current_server_time():
  18. return datetime_to_int(datetime.datetime.now())
  19. def get_jhen_event_times():
  20. """
  21. If the first int is less than the gametime at server login:
  22. If the second int is greater than the gametime at server login, fog
  23. Otherwise, if the third int is greater than the gametime at server login,
  24. sandstorm
  25. FIRST INT: Start of fog (epoch seconds)
  26. SECOND INT: Start of Jhen event (epoch seconds)
  27. THIRD INT: End of Jhen event (epoch seconds)
  28. """
  29. current_day = int(current_server_time()//SECONDS_PER_DAY)
  30. day_in_cycle = current_day % JHEN_EVENT_OFFSET
  31. if day_in_cycle < JHEN_END: # Current period
  32. cycle_start = (current_day - day_in_cycle) * SECONDS_PER_DAY
  33. else: # Upcoming period
  34. cycle_start = (current_day - day_in_cycle + JHEN_EVENT_OFFSET) * \
  35. SECONDS_PER_DAY
  36. return (int(cycle_start + FOG_START*SECONDS_PER_DAY), # fog start
  37. int(cycle_start + JHEN_START*SECONDS_PER_DAY), # sandstorm start
  38. int(cycle_start + JHEN_END*SECONDS_PER_DAY)) # sandstorm end
  39. def current_event_time_slot():
  40. """
  41. There are JHEN_EVENT_OFFSET temporal event slots per data event slot.
  42. Each one activates on a different day, counting up from 0.
  43. """
  44. return int(current_server_time()//SECONDS_PER_DAY) % JHEN_EVENT_OFFSET
  45. def is_jhen_active():
  46. day_in_cycle = int(
  47. current_server_time() // SECONDS_PER_DAY
  48. ) % JHEN_EVENT_OFFSET
  49. return JHEN_START <= day_in_cycle < JHEN_END
  50. class Timer(object):
  51. def __init__(self):
  52. self.__start = time.time()
  53. def elapsed(self):
  54. """Elapsed seconds since start"""
  55. return time.time() - self.__start
  56. def restart(self):
  57. """Reset timer and start again"""
  58. self.__start = time.time()