egebilecen / PZServerDiscordBot

A Project Zomboid Discord Bot written in C# using Discord.NET to manage and execute commands on Project Zomboid Server.
GNU General Public License v3.0
61 stars 11 forks source link

Cmd suggestions !game_time #64

Open RingerVulpe opened 1 year ago

RingerVulpe commented 1 year ago

Just a suggestion: Could you add an in-game time command? Similar to the in-game date?

egebilecen commented 1 year ago

Hey, I couldn't find the file that holds the current game time so it's not possible right now until someone enlighten me.

yangroro commented 7 months ago

I got the time value. However, this time value is only updated when the server "saves" or when the in-game time passes 0:00, so you can't rely on it to tell you the real-time time.

The method I used was to estimate the current in-game time from the ratio of in-game time to real-world time and the last time this value was saved.

So there's a slight error, but it's being corrected every day at 0:00, which gives us a pretty good in-game clock. Our server has a setup where all the zombies run from 0-4, so a lot of people take advantage of that.

Below is the python code I wrote. Note that the time_of_day is storing the minute information in the integer part and the hour information in the decimal part.


def get_in_game_datetime(path: str):
    with open(path, 'rb') as f:
        filebytes = f.read()
        time_of_day_bytes = filebytes[24:28] # its float
        day_bytes = filebytes[28:32]
        month_bytes = filebytes[32:36]
        year_bytes = filebytes[36:40]

        time_of_day = struct.unpack('>f', time_of_day_bytes)

        day = (day_bytes[0] << 24 | day_bytes[1] << 16 | day_bytes[2] << 8 | day_bytes[3]) + 1
        month = (month_bytes[0] << 24 | month_bytes[1] << 16 | month_bytes[2] << 8 | month_bytes[3]) + 1
        year = year_bytes[0] << 24 | year_bytes[1] << 16 | year_bytes[2] << 8 | year_bytes[3]

        hour = int(time_of_day[0])
        minute = int((time_of_day[0] - hour) * 60)

        mtime_timestamp = os.path.getmtime(path)
        mtime = datetime.datetime.fromtimestamp(mtime_timestamp)

        last_in_game_time = datetime.datetime(year, month, day, hour, minute)

        return last_in_game_time, mtime

I don't need to add this functionality, but I'm leaving it here for knowledge sharing.

egebilecen commented 7 months ago

Hey, thanks @yangroro. I will look at it when I have time. (Which is not any soon, unfortunately, as I am quite busy. :') I am leaving this comment for those who are waiting for this feature.)