悉野小楼

导航

自定义游戏服务端时间 C++ 11实现

原理: 系统已运行时间是不断增长的, 用户修改系统自带的时钟, 这个值不会变. 利用这个固定值加上自定义的时间长度, 计算出当前时间.

C++ 98, windows使用 GetTickCount64()取固定时间, linux使用clock_gettime(CLOCK_MONOTONIC, &tp)取固定时间

java 可以使用函数获取虚拟机已运行时间来取个固定值.

下面这个类可以优化, 使用namespace, 不使用类, 然后时间用全局变量, 不用类成员变量. 这样用namespace::mytime 这样格式可能方便些

SetUserTime(1692844734) 可以设置个自定义时间.

也可以SetUserTime(from_string("2020-10-05 12:33:55")), 

SetUserTime(0)还原成当前系统时间.

RefreshLastTime()在游戏每帧定时器里面可以调用, 定时器可以参考 定时器

 TimeSystem.h

#pragma once
#include <stdint.h>

class TimeSystem
{
public:
    TimeSystem();

    // 上一帧刷新时间增量 毫秒
    int64_t DeltaTime;

    //当前时间戳(毫秒)
    int64_t NowServerMilliseconds();
    //当前时间戳(秒)
    int64_t NowServerSeconds();

    //系统当前时间戳(毫秒)
    int64_t SysNowServerMilliseconds();
    //系统当前时间戳(秒)
    int64_t SysNowServerSeconds();

    //当前一天的0分0秒时间戳(秒)
    int32_t DayZero();

    // 刷新更新时间
    void RefreshLastTime();

    //自定义当前时间
    void SetUserTime(int32_t now);
private:

    // 操作系统已运行时间(毫秒)
    int64_t OperatingSystemRunTime();
private:
    // 上次更新时间
    int64_t    m_last_time;

    //用户增加的毫秒数
    int64_t m_user_add_time;

    friend class GameSystem;
};

 

TimeSystem.cpp

#include "TimeSystem.h"
#include <chrono>

TimeSystem::TimeSystem()
{
    //操作系统已运行时间(毫秒)
    m_last_time = OperatingSystemRunTime();
    //用户增加的毫秒数
    m_user_add_time = SysNowServerMilliseconds() - OperatingSystemRunTime();

    DeltaTime = 0;
}

int64_t TimeSystem::NowServerMilliseconds()
{
    //当前时间 = 用户时间 + 操作系统运行的时间
    return m_user_add_time + OperatingSystemRunTime();
}

int64_t TimeSystem::NowServerSeconds()
{
    return NowServerMilliseconds() / 1000;
}

int64_t TimeSystem::SysNowServerMilliseconds()
{
    return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}

int64_t TimeSystem::SysNowServerSeconds()
{
    return SysNowServerMilliseconds() / 1000;
}

int32_t TimeSystem::DayZero()
{
    time_t now_second = NowServerSeconds();
    //24*3600=86400
    int32_t sec = now_second % 86400;
    return now_second - sec;
}

// 刷新更新时间
void TimeSystem::RefreshLastTime()
{
    int64_t now_time = OperatingSystemRunTime();
    DeltaTime = now_time - m_last_time;
    if (DeltaTime < 0)
    {
        //时间回调, DeltaTime可能为负了
        DeltaTime = 0;
    }
    m_last_time = now_time;
}

//操作系统已运行时间(修改电脑时钟不会影响操作系统已运行时间)
int64_t TimeSystem::OperatingSystemRunTime()
{
    return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
}

//设置自定义时间
void TimeSystem::SetUserTime(int32_t now)
{
    if (now == 0)
    {
        //还原使用系统时间
        m_user_add_time = SysNowServerMilliseconds() - OperatingSystemRunTime();
    }
    else
    {
        m_user_add_time = now;
        m_user_add_time *= 1000;
        int64_t relative = OperatingSystemRunTime();
        m_user_add_time -= relative;
    }
}

 辅助函数两个:

#include <time.h>
#include <stdio.h>

#define TIME_LENGTH        32

std::string to_string()
{
    char szTime[TIME_LENGTH] = { 0 };
    strftime(szTime, TIME_LENGTH, "%Y-%m-%d %H:%M:%S", &m_time);
    return szTime;
}

time_t from_string(const std::string& time_str)
{
    tm tm_;
    int year, month, day, hour, minute, second;
    sscanf(time_str.c_str(), "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second);
    tm_.tm_year = year - 1900;
    tm_.tm_mon = month - 1;
    tm_.tm_mday = day;
    tm_.tm_hour = hour;
    tm_.tm_min = minute;
    tm_.tm_sec = second;
    tm_.tm_isdst = 0;
    time_t t_ = mktime(&tm_);
    return t_;
}

 

posted on 2023-08-24 10:11  悉野  阅读(29)  评论(0编辑  收藏  举报