MeikelLP / quantum-core-x

Metin2 open source server implementation
https://meikellp.github.io/quantum-core-x/
Mozilla Public License 2.0
35 stars 9 forks source link

Implement character play time #118

Closed WoozChucky closed 5 months ago

WoozChucky commented 5 months ago

Implemented the characters played time.

TLDR: Whenever EnterGame packet is handled, we save the server current uptime millis in the PlayerEntity, and then when the Logout/PhaseSelect packets are handled we fetch the time again and calculate total minutes and persist that info.

MeikelLP commented 5 months ago

What about persisting it in the DB? :)

WoozChucky commented 5 months ago

What about persisting it in the DB? :)

Hmm, await _world.DespawnPlayerAsync(context.Player); should take care of it both in SelectPhaseHandler and LogoutCommand according to the in-game test and debug that I've made. Did I missunderstood anything ?

MeikelLP commented 5 months ago

You have to adjust the function which maps PlayerData to Player (Entity) :)

WoozChucky commented 5 months ago

You have to adjust the function which maps PlayerData to Player (Entity) :)

I'm guessing that would be in DbPlayerRepository.cs: line 76, but it is already done. Or are you refering to another location? I tried to find it

    public async Task SetPlayerAsync(PlayerData data)
    {
        var entity = await _db.Players.FirstOrDefaultAsync(x => x.Id == data.Id);
        if (entity is null) return;

        entity.Empire = data.Empire;
        entity.PlayerClass = data.PlayerClass;
        entity.SkillGroup = data.SkillGroup;
        entity.PlayTime = data.PlayTime;       // it was already mapped before my pr
        entity.Level = data.Level;
        entity.Experience = data.Experience;
        entity.Gold = data.Gold;
        entity.St = data.St;
        entity.Ht = data.Ht;
        entity.Dx = data.Dx;
        entity.Iq = data.Iq;
        entity.PositionX = data.PositionX;
        entity.PositionY = data.PositionY;
        entity.Health = data.Health;
        entity.Mana = data.Mana;
        entity.Stamina = data.Stamina;
        entity.BodyPart = data.BodyPart;
        entity.HairPart = data.HairPart;
        entity.Name = data.Name;
        entity.GivenStatusPoints = data.GivenStatusPoints;
        entity.AvailableStatusPoints = data.AvailableStatusPoints;

        await _db.SaveChangesAsync();
    }
MeikelLP commented 5 months ago

What about a forced disconnect or a disconnect because connection is lost?

MeikelLP commented 5 months ago

You have to adjust the function which maps PlayerData to Player (Entity) :)

I'm guessing that would be in DbPlayerRepository.cs: line 76, but it is already done. Or are you refering to another location? I tried to find it

    public async Task SetPlayerAsync(PlayerData data)
    {
        var entity = await _db.Players.FirstOrDefaultAsync(x => x.Id == data.Id);
        if (entity is null) return;

        entity.Empire = data.Empire;
        entity.PlayerClass = data.PlayerClass;
        entity.SkillGroup = data.SkillGroup;
        entity.PlayTime = data.PlayTime;       // it was already mapped before my pr
        entity.Level = data.Level;
        entity.Experience = data.Experience;
        entity.Gold = data.Gold;
        entity.St = data.St;
        entity.Ht = data.Ht;
        entity.Dx = data.Dx;
        entity.Iq = data.Iq;
        entity.PositionX = data.PositionX;
        entity.PositionY = data.PositionY;
        entity.Health = data.Health;
        entity.Mana = data.Mana;
        entity.Stamina = data.Stamina;
        entity.BodyPart = data.BodyPart;
        entity.HairPart = data.HairPart;
        entity.Name = data.Name;
        entity.GivenStatusPoints = data.GivenStatusPoints;
        entity.AvailableStatusPoints = data.AvailableStatusPoints;

        await _db.SaveChangesAsync();
    }

Oh then nevermind :)

WoozChucky commented 5 months ago

What about a forced disconnect or a disconnect because connection is lost?

Implemented the code for when the connection is lost/dropped.

In case of a forced disconnect (from either the server, or player exiting via logout/quit) the world de-spawn should take care of it.

MeikelLP commented 5 months ago

Sorry, another thing I thought about: How about we track the players time in ms (long) and just display the number in minutes. This way we are much more accurate. Imagine how many minutes u lose just because of logging in and out

WoozChucky commented 5 months ago

Sorry, another thing I thought about: How about we track the players time in ms (long) and just display the number in minutes. This way we are much more accurate. Imagine how many minutes u lose just because of logging in and out

Agreed, and implemented the change.

MeikelLP commented 5 months ago

Pipeline is still failing. Probably due to changes in the migrations

WoozChucky commented 5 months ago

Pipeline is still failing. Probably due to changes in the migrations

Yep that was exactly it, plus a test that was failing due to player fake data giving a overflow in TimeSpan conversion of PlayTime.

Pipeline looks good now 👍