Szerző Téma: [CORE] IsBalanced()  (Megtekintve 5217 alkalommal)

Nem elérhető Shyro

  • Kezdő
  • **
  • Hozzászólások: 85
[CORE] IsBalanced()
« Dátum: 2013 Április 30, 11:15:44 pm »
Sziasztok!

Nézegettem egy két alacsony népességű magyar szervert és azt figyeltem meg, hogy nagy a létszámbeli különbség az Alliance és Horde tábor között online játékosok tekintetében. Egy kezdő szervernél ez szerintem probléma, hiszen kevesebb az esély arra, hogy indul Battleground, és egyéb következményei is lehetnek. Így erre a problémára próbáltam kiötleni valamilyen megoldást.

Terv:
- 50 és 200 online játékos közötti létszámnál vegye figyelembe a külöbség mértékét
- 15% - nál ne legyen nagyobb a két frakció százalékos eltérése
- Túl magas eltérés esetén ne engedélyezze a nagyobb létszámú frakcióba tartozó karakter belépését


Megvalósítás:

Szükséges fájlok:
  • World.h
  • World.cpp
  • Player.cpp
  • WorldSession.h
  • CharacterHandler.cpp
Módosítandó részek:

~World.h
A World.h header fájlban szükségünk lesz két változóra, melyek az aktuális létszámot tárolják az adott frakciókból (a szerver létszáma mellett). Ezeket a World osztály private részében kell definiálni:
uint32 m_PlayerACount;
uint32 m_PlayerHCount;
Gondolkodni kell ezen értékek elérhetőségéről is, így a public részben:
inline uint32 GetPlayerACount() const { return m_PlayerACount; }
inline uint32 GetPlayerHCount() const { return m_PlayerHCount; }
Minden egyes játékos belépésénél az m_PlayerCount változó értéke eggyel nő, ezt a műveletet az IncreasePlayerCount() függvény végzi. Mivel mi szeretnénk növelni ugyanakkor az m_PlayerACount és m_PlayerHCount változók értékét is, kicsit módosítanunk kell a függvényt:
inline void IncreasePlayerCount(uint32 faction)
{
    m_PlayerCount++;
    m_MaxPlayerCount = std::max(m_MaxPlayerCount, m_PlayerCount);

    switch(faction)
    {
        case ALLIANCE:
            m_PlayerACount++;
        break;

        case HORDE:
            m_PlayerHCount++;
        break;
    }
}
Természetesen gondoskodni kell arról, hogy adott játékos kijelentkezése esetében ezek az értékek csökkenjenek:
inline void DecreasePlayerCount(uint32 faction)
{
    m_PlayerCount--;

    switch(faction)
    {
        case ALLIANCE:
            m_PlayerACount--;
        break;

        case HORDE:
            m_PlayerHCount--;
        break;
    }
}

~World.cpp
Nem szabad megfeledkezni az általunk használt változók kezdőértékeinek megadásáról. Ezt a World.cpp fájlban a World osztály konstruktorában tesszük meg, az m_PlayerCount változó kezdőértékének megadásának mintájára:
m_PlayerACount = 0;
m_PlayerHCount = 0;

~Player.cpp
Mikor fognak meghívódni az IncreasePlayerCount() és DecreasePlayerCount() függvényeink? A Player.cpp fájlban a Player osztály konstruktorában és destruktorában, hiszen minden ilyen objektum létrejöttekor növeljük a játékosok számát, és "pusztulásakor" csökkentjük azt. Mivel paramétert adtunk meg a függvények definiálásánál, így használatukkor a függvény egy paramétert vár, amit most meg kell adnunk:

Konstruktorban:
sWorld->IncreasePlayerCount(Player::TeamForRace(getRace()));Destruktorban:
sWorld->DecreasePlayerCount(Player::TeamForRace(getRace()));A módosított függvényt a konstruktor esetében a függvény végébe destruktor esetében az elejébe kell helyezni.

Hibalehetőségek:
- Elméletileg a konstruktorban is meghívható a getRace() függvény, ha mégsem, az oka, hogy még nincs érték, melyet visszaadhatna. Nekem azt mondták, hogy rendelkezik ekkor már megfelelő visszatérési értékkel, de a biztonság kedvéért érdemes a végébe tenni a kódrészletet.
- Szerintem ha meg is hívható, akkor maximum a formáva lehet probléma: illene oda egy this a Player helyére (talán)

~WorldSession.h
Már megvannak a megfelelő változóink, melyekkel már kalkulálhatunk, már csak a függvény hiányzik, amely a döntést végzi (beléphet e a játékos, avagy sem). Ezt a függvényt a WorldSession.h header fájlban a WorldSession osztály public részében kell definiálni. Az ok erre csak annyi, hogy a CharacterHandler.cpp majd innen veszi a függvényt.
bool IsBalanced(uint32 _count, uint32 _acount, uint32 _hcount, uint8 _race)
{
uint32 apercent = ((_acount.ToDouble / _count.ToDouble) * 100).ToUInt32;
uint32 hpercent = ((_hcount.ToDouble / _count.ToDouble) * 100).ToUInt32;

if(_count > 50 && _count < 200)
if(apercent > hpercent)
    if((apercent - hpercent) > 15)
        switch(Player::TeamForRace(_race))
        {
            case ALLIANCE:
                return false;
            break;

            case HORDE:
                return true;
            break;
        }
    else if(apercent < hpercent)
    if((hpercent - apercent) > 15)
        switch(Player::TeamForRace(_race))
        {
            case ALLIANCE:
                return true;
            break;

            case HORDE:
                return false;
            break;
        }

    return true;
}

~CharacterHandler.cpp
A függvényünket már csak meg kell hívni a megfelelő helyen a megfelelő paraméterekkel. A CharacterHandler.cpp fájl
void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData)függvényében kell elhelyeznünk a következő sorokat:
uint32 race = 0;(Alapvetően nem kérdezi le a race értékét, de nekünk szükségünk lesz rá.)
recvData >> race;(Ezt mindenképpen a recvData >> playerGuid; sor alá kell beszúrnunk, ugyanis a recvData egy adathalmaz, mely esetében a 2. komponens tartalmazza az adott race értéket.)
if(!IsBalanced(GetPlayerCount(), GetPlayerACount(), GetPlayerHCount(), race))
{
    sLog->outError(LOG_FILTER_NETWORKIO, "Account (%u) can't login with that character (%u).", GetAccountId(), GUID_LOPART(playerGuid));
    KickPlayer();
    return;
}
Ha a játékosunk nem a megfelelő frakciójú karakterrel szeretne bejelentkezni, egyszerüen nem fog tudni.

Hibalehetőségek:

- Ha nem a megfelelő helyre szúrtuk be a kódrészleteinket, akkor ki kell találni, hogy mégis hova kellene.

~Vélemény
A TrinityCore borzasztóan rosszul kommentelt, nem megfelelően dokumentált (inkább egyátalán nem). Nagyon nehéz egy olyan kódtömeget megismerni, amit valakik valamikor kitaláltak, lekódoltak és nem biztosítottak hozzá megfelelő leírást, hogy mi micsoda.
Mivel nem ismerem a TrinityCore működését, így egy ilyen kis nyámnyila kód megírása is nehézséget okozott: honnan kapja ez az értéket, hol van az definiálva... stb.
Ez az oka a sok hibalehetőségnek, mert az ember csak tippelni tud. Avagy tesztelni.

~FONTOS
Nem debuggoltam, nem teszteltem. Egyrészt erre nincs is lehetőségem, másrészt nem is szeretném. :) Akinek van módja és kedve tesztelni, az hibák kapcsán írjon, mindenképpen érdekelni fog. Úgy gondolom, kiindulópontnak ez megfelelő.
« Utoljára szerkesztve: 2013 Április 30, 11:41:13 pm írta Shyro »
makeSystem :: Integral a => [a] -> [a]
makeSystem l = concat (zipWith (\ a b -> replicate (fromIntegral a) (fromIntegral b)) l [ product x | x <- inits l ])
makeSystem [ 60, 60, 24, 7, 52 ] = ?

Nem elérhető EroniX

  • Középhaladó
  • ***
  • Hozzászólások: 224
  • www.azuregoswow.com
  • Op. Rendszer: Windows 8 Pro x64
Re:[CORE] IsBalanced()
« Válasz #1 Dátum: 2013 Április 30, 11:31:56 pm »
Nagyon jó ötlet, és micsoda kód!

if(_count > 50 && _count < 200)
if(apercent > hpercent)
    if((apercent - hpercent) > 15)
        switch(Player::TeamForRace(_race))
        {
            case ALLIANCE:
                return false;
            break;

            case HORDE:
                return true;
            break;
        }
    else if(apercent < hpercent)
    if((hpercent - apercent) > 15)
        switch(Player::TeamForRace(_race))
        {
            case ALLIANCE:
                return true;
            break;

            case HORDE:
                return false;
            break;
        }

    return true;
}

Ezt így írtam volna meg:
if(_count > 50 && _count < 200)
{
uint32 biggerTeam = (apercent > hpercent) ? ALLIANCE : HORDE;
if(abs(apercent - hpercent) > 15 && Player::TeamForRace(_race) == biggerTeam)
return false;

return true;
}

De a tiéd is tökéletes, szép munka. :)
« Utoljára szerkesztve: 2013 Április 30, 11:36:05 pm írta EroniX »
Azuregos Delta Force

Nem elérhető Shyro

  • Kezdő
  • **
  • Hozzászólások: 85
Re:[CORE] IsBalanced()
« Válasz #2 Dátum: 2013 Április 30, 11:34:54 pm »
Jogos, korrektebb a megoldásod. Nekem is jobban tetszik.  ;D

Sőt, most nézem, hogy nálam kell az a kapcsos! (fixálom) or not
« Utoljára szerkesztve: 2013 Április 30, 11:41:27 pm írta Shyro »
makeSystem :: Integral a => [a] -> [a]
makeSystem l = concat (zipWith (\ a b -> replicate (fromIntegral a) (fromIntegral b)) l [ product x | x <- inits l ])
makeSystem [ 60, 60, 24, 7, 52 ] = ?

Nem elérhető Bluerák

  • Globális Moderátor
  • Elvetemült
  • *****
  • Hozzászólások: 682
Re:[CORE] IsBalanced()
« Válasz #3 Dátum: 2013 Május 01, 12:19:05 am »
Szuper ötlet, de például ha én nem csinálhatnék allist, akkor biztos nem játszanék azon a bizonyos szerveren.  :D
De remek kód és a megvalósítás is +1.

MacBook Pro 13' 2.26 GHZ, 4 GB RAM - White
iPhone 4S 16GB - Black
iPad 3 - Black

NEW PC:
Asus EAH6670 (1GB 128 bit)
AMD FX AM3+ (4x3.8GHZ)
ASRock 970 EXTREME3
8GB RAM

Nem elérhető Shyro

  • Kezdő
  • **
  • Hozzászólások: 85
Re:[CORE] IsBalanced()
« Válasz #4 Dátum: 2013 Május 01, 01:28:32 am »
Alliance - os karaktert még készíthetsz, csak nem léphetsz be vele. Biztos, hogy menne az idegeskedés. Bár, akkor is megy, ha nincs ellenfél nem?  ;D
makeSystem :: Integral a => [a] -> [a]
makeSystem l = concat (zipWith (\ a b -> replicate (fromIntegral a) (fromIntegral b)) l [ product x | x <- inits l ])
makeSystem [ 60, 60, 24, 7, 52 ] = ?

Nem elérhető Naxon90

  • Újonc
  • *
  • Hozzászólások: 16
Re:[CORE] IsBalanced()
« Válasz #5 Dátum: 2013 Május 01, 10:28:24 am »
Ez elképesztő,szép munka! :)

Nem elérhető Bluerák

  • Globális Moderátor
  • Elvetemült
  • *****
  • Hozzászólások: 682
Re:[CORE] IsBalanced()
« Válasz #6 Dátum: 2013 Május 01, 12:39:52 pm »
Alliance - os karaktert még készíthetsz, csak nem léphetsz be vele. Biztos, hogy menne az idegeskedés. Bár, akkor is megy, ha nincs ellenfél nem?  ;D
Az még idegesítőbb.  :P

MacBook Pro 13' 2.26 GHZ, 4 GB RAM - White
iPhone 4S 16GB - Black
iPad 3 - Black

NEW PC:
Asus EAH6670 (1GB 128 bit)
AMD FX AM3+ (4x3.8GHZ)
ASRock 970 EXTREME3
8GB RAM

 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27