Esempio n. 1
0
void sendEntitiesList(Player *player)
{
    levelLoadMutex.lock(); // Protect player->inGame
    if (player->inGame == 0) // Not yet in game, send player's ponies list (Characters scene)
    {
        levelLoadMutex.unlock();
#if DEBUG_LOG
        win.logMessage("UDP: Sending ponies list");
#endif
        sendPonies(player);
        return;
    }
    else if (player->inGame > 1) // Not supposed to happen, let's do it anyway
    {
        //levelLoadMutex.unlock();
        win.logMessage(QString("UDP: Entities list already sent to ")+QString().setNum(player->pony.netviewId)
                       +", resending anyway");
        //return;
    }
    else // Loading finished, sending entities list
    win.logMessage(QString("UDP: Sending entities list to ")+QString().setNum(player->pony.netviewId));
    Scene* scene = findScene(player->pony.sceneName); // Spawn all the players on the client
    for (int i=0; i<scene->players.size(); i++)
        sendNetviewInstantiate(&scene->players[i]->pony, player);

    // Send npcs
    for (int i=0; i<win.npcs.size(); i++)
        if (win.npcs[i]->sceneName.toLower() == player->pony.sceneName.toLower())
        {
#if DEBUG_LOG
            win.logMessage("UDP: Sending NPC "+win.npcs[i]->name);
#endif
            sendNetviewInstantiate(win.npcs[i], player);
        }

    // Spawn some mobs in Zecoras
    if (scene->name.toLower() == "zecoras")
    {
        sendNetviewInstantiate(player,"mobs/dragon", win.getNewId(), win.getNewNetviewId(), {-33.0408, 0.000425577, 101.766}, {0,-1,0,1});
    }

    player->inGame = 2;
    levelLoadMutex.unlock();

    // Send stats of the client's pony
    sendSetMaxStatRPC(player, 0, 100);
    sendSetStatRPC(player, 0, 100);
    sendSetMaxStatRPC(player, 1, 100);
    sendSetStatRPC(player, 1, 100);
}
Esempio n. 2
0
void sendEntitiesList(Player *player)
{
    levelLoadMutex.lock(); // Protect player->inGame
    if (player->inGame == 0) // Not yet in game, send player's ponies list (Characters scene)
    {
        levelLoadMutex.unlock();
        sendPonies(player);
        return;
    }
    else if (player->inGame > 1) // Not supposed to happen, let's do it anyway
    {
        //levelLoadMutex.unlock();
        win.logMessage(QString("UDP: Entities list already sent to ")+QString().setNum(player->pony.netviewId)
                       +", resending anyway");
        //return;
    }
    else // Loading finished, sending entities list
    win.logMessage(QString("UDP: Sending entities list to ")+QString().setNum(player->pony.netviewId));
    Scene* scene = findScene(player->pony.sceneName); // Spawn all the players on the client
    for (int i=0; i<scene->players.size(); i++)
        sendNetviewInstantiate(scene->players[i], player);

    /// SEND DONUT STEEL (in front of the mirror)
    if (scene->name == "RaritysBoutique")
    {
        win.logMessage(QString("UDP: Sending Donut Steel to ")+QString().setNum(player->pony.netviewId));
        sendNetviewInstantiate(player,"PlayerBase",0,0,UVector(24.7333,-1.16802,-51.7106), UQuaternion(0,-0.25,0,1));
    }

    player->inGame = 2;
    levelLoadMutex.unlock();

    // Send stats of the client's pony
    sendSetMaxStatRPC(player, 0, 100);
    sendSetStatRPC(player, 0, 100);
    sendSetMaxStatRPC(player, 1, 100);
    sendSetStatRPC(player, 1, 100);
}
Esempio n. 3
0
void Pony::takeDamage(unsigned amount)
{
    if (health <= (float)amount/defense)
        kill();
    else
    {
        health -= (float)amount/defense;
        Scene* scene = findScene(sceneName);
        for (Player* player : scene->players)
        {
            sendSetStatRPC(player, netviewId, 1, health);
        }
    }
}
Esempio n. 4
0
void sendPonySave(Player *player, QByteArray msg)
{
    if (player->inGame < 2) // Not supposed to happen, ignoring the request
    {
        win.logMessage("UDP: Savegame requested too soon by "+QString().setNum(player->pony.netviewId));
        return;
    }

    quint16 netviewId = (quint8)msg[6] + ((quint8)msg[7]<<8);
    Player* refresh = Player::findPlayer(win.udpPlayers, netviewId);

    if (netviewId == player->pony.netviewId)
    {
        if (player->inGame == 3) // Hopefully that'll fix people stuck on the default cam without creating clones
        {
            win.logMessage("UDP: Savegame already sent to "+QString().setNum(player->pony.netviewId)
                           +", resending anyway");
        }
        else
            win.logMessage(QString("UDP: Sending pony save for/to ")+QString().setNum(netviewId));

        // Set current/max stats
        sendSetMaxStatRPC(player, 0, 100);
        sendSetStatRPC(player, 0, 100);
        sendSetMaxStatRPC(player, 1, 100);
        sendSetStatRPC(player, 1, 100);

        sendPonyData(player);

        // Set inventory (start with always the same, until we implement it properly)
        InventoryItem raincloudHat;
        raincloudHat.id=73;
        raincloudHat.index=0;
        InventoryItem goggles;
        goggles.id=17;
        goggles.index=1;
        InventoryItem hat;
        hat.id=62;
        hat.index=2;
        InventoryItem bag;
        bag.id=60;
        bag.index=3;
        player->inv.clear();
        player->inv << raincloudHat << goggles << hat << bag;
        player->worn.clear();
        //player->worn << goggles << bag;
        player->nBits = 15;
        sendInventoryRPC(player, player->inv, player->worn, player->nBits);

        // Send skills
        QList<QPair<quint32, quint32> > skills;
        skills << QPair<quint32, quint32>(10, 0); // Ground pound
        if (player->pony.getType() == Pony::EarthPony)
            skills << QPair<quint32, quint32>(5, 0); // Seismic buck
        else if (player->pony.getType() == Pony::Pegasus)
            skills << QPair<quint32, quint32>(11, 0); // Tornado
        else if (player->pony.getType() == Pony::Unicorn)
            skills << QPair<quint32, quint32>(2, 0); // Teleport
        sendSkillsRPC(player, skills);

        // Set current/max stats again (that's what the official server does, not my idea !)
        sendSetMaxStatRPC(player, 0, 100);
        sendSetStatRPC(player, 0, 100);
        sendSetMaxStatRPC(player, 1, 100);
        sendSetStatRPC(player, 1, 100);

        /// SEND DONUT STEEL (he's a moose dark-as-my-soul OC)
        if (player->pony.sceneName == "RaritysBoutique")
        {
            win.logMessage("UDP: Sending pony save for Donut Steel to "+QString().setNum(player->pony.netviewId));
            Player donutSteel;
            donutSteel.pony.id = donutSteel.pony.netviewId = 0;
            donutSteel.pony.ponyData = QByteArray::fromHex("0b446f6e757420537465656c0402b70000000000000000000000ca1a0017ff00032e03ff050072ff000c000b0000000000cdcc8c3fff9f");
            sendPonyData(&donutSteel, player);
        }

        refresh->inGame = 3;
    }
    else if (!refresh->IP.isEmpty())
    {
        win.logMessage(QString("UDP: Sending pony save for ")+QString().setNum(refresh->pony.netviewId)
                       +" to "+QString().setNum(player->pony.netviewId));

        sendWornRPC(refresh, player, refresh->worn);

        sendSetStatRPC(refresh, player, 0, 100);
        sendSetMaxStatRPC(refresh, player, 0, 100);
        sendSetStatRPC(refresh, player, 1, 100);
        sendSetMaxStatRPC(refresh, player, 1, 100);

        sendPonyData(refresh, player);

        if (!refresh->lastValidReceivedAnimation.isEmpty())
            sendMessage(player, MsgUserReliableOrdered12, refresh->lastValidReceivedAnimation);
    }
    else
    {
        win.logMessage("UDP: Error sending pony save : netviewId "+QString().setNum(netviewId)+" not found");
    }
}
void receiveChatMessage(QByteArray msg, Player* player)
{
    QString txt = dataToString(msg.mid(7));
    QString author = player->pony.name;
    //logMessage("Chat "+author+":"+txt);

    if (txt.startsWith("/stuck") || txt.startsWith("unstuck me"))
    {
        sendLoadSceneRPC(player, player->pony.sceneName);
    }
    else if (txt == ":anhero")
    {
        QTimer *anheroTimer = new QTimer();
        anheroTimer->setSingleShot(true);

        QString deadPlayerName = player->name;

        QObject::connect(anheroTimer, &QTimer::timeout, [=]() {
            // Find player again instead of reusing pointer, in case they disconnect
            Player* deadPlayer = Player::findPlayer(Player::udpPlayers, deadPlayerName);
            if (deadPlayer->connected && deadPlayer->pony.dead) {
                sendSetStatRPC(deadPlayer, 1, deadPlayer->pony.health);
                Scene* scene = findScene(deadPlayer->pony.sceneName);
                for (Player* other : scene->players)
                    sendNetviewInstantiate(&deadPlayer->pony, other);
                deadPlayer->pony.dead = false;
            }
            delete anheroTimer;
            // Don't delete deadPlayer here. That kills the player's session
          } );
        if (!player->pony.dead)
        {
            player->pony.dead = true;
            sendSetStatRPC(player, 1, 0);
            anheroTimer->start(5000);
            Scene* scene = findScene(player->pony.sceneName);
            for (Player* other : scene->players)
                sendNetviewRemove(other, player->pony.netviewId, NetviewRemoveReasonKill);
        }
    }
    else if (txt == ":commands")
    {
        sendChatMessage(player, "<span color=\"yellow\">List of Commands:</span><br /><em>:roll</em><br /><span color=\"yellow\">Rolls a random number between 00 and 99</span><br /><em>:msg player message</em><br /><span color=\"yellow\">Sends a private message to a player</span><br /><em>:names</em><br /><span color=\"yellow\">Lists all players on the server</span><br /><em>:me action</em><br /><span color=\"yellow\">States your current action</span><br /><em>:tp location</em><br /><span color=\"yellow\">Teleports your pony to the specified region</span>", "[Server]", ChatLocal);
    }
    else if (txt.startsWith(":msg"))
    {
        if(txt.count(" ") < 2)
            sendChatMessage(player, ":msg<br /><span color=\"yellow\">Usage:</span><br /><em>:msg player message</em><br /><span color=\"yellow\">Player names are case-insensitive, ignore spaces and you do not need to type out their full name.</span>", author, ChatLocal);
        else
        {
            for (int i=0; i<Player::udpPlayers.size(); i++)
            {
                if (Player::udpPlayers[i]->inGame>=2 && Player::udpPlayers[i]->pony.name.toLower().remove(" ")
                        .startsWith(txt.toLower().section(" ", 1, 1)))
                {
                    txt = txt.remove(0, txt.indexOf(" ", 5) + 1);
                    sendChatMessage(Player::udpPlayers[i], "<span color=\"yellow\">[PM] </span>" + txt, author, ChatLocal);
                    sendChatMessage(player, "<span color=\"yellow\">[PM to "
                                    + Player::udpPlayers[i]->pony.name + "] </span>" + txt, author, ChatLocal);
                }
            }
        }
    }
    else if (txt.startsWith(":names"))
    {
        QString namesmsg = "<span color=\"yellow\">Players currently in game:</span>";

        for (int i=0; i<Player::udpPlayers.size(); i++)
            if (Player::udpPlayers[i]->inGame>=2)
                namesmsg += "<br />#b" + Player::udpPlayers[i]->pony.name
                        + "#b<br /><span color=\"yellow\"> - in "
                        + Player::udpPlayers[i]->pony.sceneName + "</span>";

        sendChatMessage(player, namesmsg, "[Server]", ChatLocal);
    }
    else if (txt.startsWith(":tp"))
    {
        if (txt.count(" ") < 1)
        {
          QString msgtosend = ":tp<br /><span color=\"yellow\">Usage:</span><br /><em>:tp location</em><br /><span color=\"yellow\">Available locations:</span><em>";

            for (int i=0; i<Scene::scenes.size(); i++)
                msgtosend += "<br />" + Scene::scenes[i].name;

            sendChatMessage(player, msgtosend + "</em>", author, ChatLocal);
        }

        else
            sendLoadSceneRPC(player, txt.remove(0, 4));
    }
    else if (txt == ":me")
    {
        sendChatMessage(player, ":me<br /><span color=\"yellow\">Usage:</span><br /><em>:me action</em>", author, ChatLocal);
    }
    else // Broadcast the message
    {
        int rollnum = -1;
        QString rollstr;
        bool actmsg = false;

        if (txt == ":roll")
        {
            if (player->chatRollCooldownEnd < QDateTime::currentDateTime())
            {
                rollnum = qrand() % 100;
                rollstr.sprintf("<span color=\"yellow\">#b%s#b rolls %02d</span>", author.toLocal8Bit().data(), rollnum);
                player->chatRollCooldownEnd = QDateTime::currentDateTime().addSecs(10);
            }
        }
        if (txt.startsWith(":me "))
        {
            actmsg = true;
            txt.remove(0, 3);
            txt = "<em>#b* " + author + "#b" + txt + "</em>";
        }
        if ((quint8)msg[6] == 8) // Local chat only
        {
            Scene* scene = findScene(player->pony.sceneName);
            if (scene->name.isEmpty())
                logMessage(QObject::tr("UDP: Can't find the scene for chat message, aborting"));
            else
            {
                for (int i=0; i<scene->players.size(); i++)
                {
                    if (scene->players[i]->inGame>=2)
                    {
                        if (rollnum > -1)
                            sendChatMessage(scene->players[i], rollstr, "[Server]", ChatLocal);
                        else if (actmsg)
                            sendChatMessage(scene->players[i], txt, "", ChatLocal);
                        else if (txt.startsWith(">"))
                            sendChatMessage(scene->players[i], "<span color=\"green\">" + txt + "</span>", author, ChatLocal);
                        else
                            sendChatMessage(scene->players[i], txt, author, ChatLocal);
                    }
                }
            }
        }
        else // Send globally
        {
            for (int i=0; i<Player::udpPlayers.size(); i++)
            {
                if (Player::udpPlayers[i]->inGame>=2)
                {
                    if (rollnum > -1)
                        sendChatMessage(Player::udpPlayers[i], rollstr, "[Server]", ChatGeneral);
                    else if (actmsg)
                        sendChatMessage(Player::udpPlayers[i], txt, "", ChatGeneral);
                    else if (txt.startsWith(">"))
                        sendChatMessage(Player::udpPlayers[i], "<span color=\"green\">" + txt + "</span>", author, ChatGeneral);
                    else
                        sendChatMessage(Player::udpPlayers[i], txt, author, ChatGeneral);

                }
            }
        }
    }
}
Esempio n. 6
0
void sendPonySave(Player *player, QByteArray msg)
{
    if (player->inGame < 2) // Not supposed to happen, ignoring the request
    {
        win.logMessage("UDP: Savegame requested too soon by "+QString().setNum(player->pony.netviewId));
        return;
    }

    quint16 netviewId = (quint8)msg[6] + ((quint16)(quint8)msg[7]<<8);
    Player* refresh = Player::findPlayer(win.udpPlayers, netviewId); // Find players

    // Find NPC
    Pony* npc = NULL;
    for (int i=0; i<win.npcs.size(); i++)
        if (win.npcs[i]->netviewId == netviewId)
            npc = win.npcs[i];

    // If we found a matching NPC, send him and exits
    if (npc != NULL)
    {
#if DEBUG_LOG
        win.logMessage("UDP: Sending ponyData and worn items for NPC "+npc->name);
#endif
        sendPonyData(npc, player);

        if (npc->inv.size()) // This NPC has a shop
        {
            sendAddViewAddShop(player, npc);
        }

        return;
    }

    if (netviewId == player->pony.netviewId) // Current player
    {
        if (player->inGame == 3) // Hopefully that'll fix people stuck on the default cam without creating clones
        {
            win.logMessage("UDP: Savegame already sent to "+QString().setNum(player->pony.netviewId)
                           +", resending anyway");
        }
        else
            win.logMessage(QString("UDP: Sending pony save for/to ")+QString().setNum(netviewId));

        // Set current/max stats
        sendSetMaxStatRPC(player, 0, 100);
        sendSetStatRPC(player, 0, 100);
        sendSetMaxStatRPC(player, 1, 100);
        sendSetStatRPC(player, 1, 100);

        sendPonyData(player);

        // Send inventory
        sendInventoryRPC(player, player->pony.inv, player->pony.worn, player->pony.nBits);

        // Send skills
        QList<QPair<quint32, quint32> > skills;
        skills << QPair<quint32, quint32>(10, 0); // Ground pound (all races)
        if (player->pony.getType() == Pony::EarthPony)
        {
            skills << QPair<quint32, quint32>(5, 0); // Seismic buck
            skills << QPair<quint32, quint32>(16, 0); // Rough Terrain
        }
        else if (player->pony.getType() == Pony::Pegasus)
        {
            skills << QPair<quint32, quint32>(11, 0); // Dual Cyclone
            skills << QPair<quint32, quint32>(14, 0); // Gale
        }
        else if (player->pony.getType() == Pony::Unicorn)
        {
            skills << QPair<quint32, quint32>(2, 0); // Teleport
            skills << QPair<quint32, quint32>(9, 0); // Rainbow Fields
            skills << QPair<quint32, quint32>(12, 0); // Heal
            skills << QPair<quint32, quint32>(15, 0); // Magical Arrow
        }
        sendSkillsRPC(player, skills);

        // Set current/max stats again (that's what the official server does, not my idea !)
        sendSetMaxStatRPC(player, 0, 100);
        sendSetStatRPC(player, 0, 100);
        sendSetMaxStatRPC(player, 1, 100);
        sendSetStatRPC(player, 1, 100);

        refresh->inGame = 3;
    }
    else if (!refresh->IP.isEmpty())
    {
        win.logMessage(QString("UDP: Sending pony save for ")+QString().setNum(refresh->pony.netviewId)
                       +" to "+QString().setNum(player->pony.netviewId));

        //sendWornRPC(refresh, player, refresh->worn);

        sendSetStatRPC(refresh, player, 0, 100);
        sendSetMaxStatRPC(refresh, player, 0, 100);
        sendSetStatRPC(refresh, player, 1, 100);
        sendSetMaxStatRPC(refresh, player, 1, 100);

        sendPonyData(&refresh->pony, player);

        if (!refresh->lastValidReceivedAnimation.isEmpty())
            sendMessage(player, MsgUserReliableOrdered12, refresh->lastValidReceivedAnimation);
    }
    else
    {
        win.logMessage("UDP: Error sending pony save : netviewId "+QString().setNum(netviewId)+" not found");
    }
}