azerothcore / mod-arena-3v3-solo-queue

This module allows you to create groups of 3 against 3. It is still in development.
GNU Affero General Public License v3.0
2 stars 4 forks source link

Bug: Rating/Win/Loss doesnt count after the game ends #8

Open laasker opened 4 months ago

laasker commented 4 months ago

Current Behaviour

After an solo queue game ends, the player ratings/win/loss doenst change, they stay at 0.

Edit: On the db table log_arena_fights, it says how much mmr/rating etc is changed, but it's using the temporary solo 'arena_team' ID. This is being called in 'Arena::EndBattleground' at Arena.cpp. Also 'Arena::EndBattleground' calls 'ArenaTeam::SaveToDB' that then saves the games/MMR/update ratings etc.

To save the player real solo 3v3 team, this should be called if a team ID is >= 0xFFF00000:

void Solo3v3::SaveSoloDB(ArenaTeam* team)

Expected Behaviour

The player arena solo team should update the rating/games/wins/loss/mmr after the soloq arena ends, since it is a Rated arena

Steps to reproduce the problem

.

Extra Notes

Can see more here, i think the module look a lot like the core mod in this commit

https://github.com/retrydev/sunwellcore-3v3-solo/commit/fe049f83ebafccedb094c9890483f59deb1feb01#diff-e85c66aeea2d435833410cb73537599fa610eea8364ebdf5e4bf71f4260bd4d9R197

AC rev. hash/commit

.

Operating system

win 10 x64

Custom changes or Modules

No response

laasker commented 3 months ago

Ok, for the 'void Solo3v3::CleanUp3v3SoloQ(Battleground* bg)' we can just use the hook OnBattlegroundDestroy, in solo3v3_sc.cpp:

void Solo3v3BG::OnBattlegroundDestroy(Battleground* bg)
{
    sSolo->CleanUp3v3SoloQ(bg);
}

And for the SaveSoloDB i honestly don't know. I tried to change ArenaTeam.cpp https://github.com/azerothcore/azerothcore-wotlk/blob/c9bdf4c0ef721453137508560e759cb7dda02e12/src/server/game/Battlegrounds/ArenaTeam.cpp#L934 by adding

    if (TeamId >= 0xFFF00000)
    {
        SaveSoloDB(this);
        return;
    }

And below void ArenaTeam::SaveToDB(bool forceMemberSave), adding the 'SaveSoloDB' code from the module:

void ArenaTeam::SaveSoloDB(ArenaTeam* team)
{
    if (!team)
        return;

    // Init some variables for speedup the programm
    ArenaTeam* realTeams[3];
    uint32 itrRealTeam = 0;

    for (; itrRealTeam < 3; itrRealTeam++)
        realTeams[itrRealTeam] = nullptr;

    itrRealTeam = 0;
    uint32 oldRating = 0;

    // First get the old average rating by looping through all members in temp team and add up the rating
    for (auto const& itr : team->GetMembers())
    {
        ArenaTeam* plrArenaTeam = nullptr;

        // Find real arena team for player
        for (auto const& itrMgr : sArenaTeamMgr->GetArenaTeams())
        {
            if (itrMgr.first < 0xFFF00000 && itrMgr.second->GetCaptain() == itr.Guid && itrMgr.second->GetType() == 4)
            {
                plrArenaTeam = itrMgr.second; // found!
                LOG_ERROR("solo3v3", "SaveSoloDB - Found 3v3 Solo Team");
                break;
            }
        }

        if (!plrArenaTeam)
            continue; // Not found? Maybe player has left the game and deleted it before the arena game ends.

        ASSERT(itrRealTeam < 3);
        realTeams[itrRealTeam++] = plrArenaTeam;

        oldRating += plrArenaTeam->GetRating(); // add up all ratings from each player team
    }

    if (team->GetMembersSize() > 0)
        oldRating /= team->GetMembersSize(); // Get average

    int32 ratingModifier = team->GetRating() - oldRating; // GetRating() contains the new rating and oldRating is the old average rating

    itrRealTeam = 0;

    // Let's loop again through temp arena team and add the new rating
    for (auto const& _itr : team->GetMembers())
    {
        ArenaTeam* plrArenaTeam = realTeams[itrRealTeam++];

        if (!plrArenaTeam)
            continue;

        ArenaTeamStats atStats = plrArenaTeam->GetStats();

        if (int32(atStats.Rating) + ratingModifier < 0)
            atStats.Rating = 0;
        else
            atStats.Rating += ratingModifier;

        atStats.SeasonGames = _itr.SeasonGames;
        atStats.SeasonWins = _itr.SeasonWins;
        atStats.WeekGames = _itr.WeekGames;
        atStats.WeekWins = _itr.WeekWins;

        for (auto realMemberItr : plrArenaTeam->GetMembers())
        {
            if (realMemberItr.Guid != plrArenaTeam->GetCaptain())
                continue;

            realMemberItr.PersonalRating = _itr.PersonalRating;
            realMemberItr.MatchMakerRating = _itr.MatchMakerRating;
            realMemberItr.SeasonGames = _itr.SeasonGames;
            realMemberItr.SeasonWins = _itr.SeasonWins;
            realMemberItr.WeekGames = _itr.WeekGames;
            realMemberItr.WeekWins = _itr.WeekWins;
        }

        plrArenaTeam->SetArenaTeamStats(atStats);
        plrArenaTeam->NotifyStatsChanged();
        plrArenaTeam->SaveToDB();
    }
}

But it doesnt find the correctly solo 3v3 team of players at " if (itrMgr.first < 0xFFF00000 && itrMgr.second->GetCaptain() == itr.Guid && itrMgr.second->GetType() == 4)"

I need help in that

Helias commented 3 months ago

I need more time to investigate about this and understand it better.

Why do you use this filter? if (TeamId >= 0xFFF00000) ?

laasker commented 3 months ago

Why do you use this filter? if (TeamId >= 0xFFF00000) ?

I just copied https://github.com/retrydev/sunwellcore-3v3-solo/commit/fe049f83ebafccedb094c9890483f59deb1feb01#diff-e85c66aeea2d435833410cb73537599fa610eea8364ebdf5e4bf71f4260bd4d9R197

And from what i have seen it's the team ID for Solo 3v3. I may be wrong but when the player is on the solo 3v3 queue, a new temporary team is created to merge 3 players that are on the queue in a single (temporary) team. In here https://github.com/azerothcore/mod-arena-3v3-solo-queue/blob/b8f988e47bb593990c2db71b72e3742a9c681270/src/solo3v3_sc.cpp#L421

And the arena teams are override in https://github.com/azerothcore/mod-arena-3v3-solo-queue/blob/b8f988e47bb593990c2db71b72e3742a9c681270/src/solo3v3_sc.cpp#L432

And when the arena ends, when saving the teams, if it's a 3v3 solo we need to get the players real team ID instead of that temporary team that is deleted after the arena ends

Helias commented 3 months ago

ok, by the way, in this period I do not have much time to improve this unfortunately :(

laasker commented 3 months ago

It's fine, maybe someone else could take a look at this too